void Reshape(GLuint vp_width, GLuint vp_height) {
        width = vp_width;
        height = vp_height;

        float aspect = float(width) / height;

        auto projection = CamMatrixf::PerspectiveX(Degrees(60), aspect, 1, 20);

        plane_projection_matrix.Set(projection);
        shape_projection_matrix.Set(projection);

        gl.Bound(Texture::Target::Rectangle, depth_tex)
          .Image2D(
            0,
            PixelDataInternalFormat::DepthComponent,
            width / tex_size_div,
            height / tex_size_div,
            0,
            PixelDataFormat::DepthComponent,
            PixelDataType::Float,
            nullptr);
        gl.Bound(Texture::Target::Rectangle, reflect_tex)
          .Image2D(
            0,
            PixelDataInternalFormat::RGB,
            width / tex_size_div,
            height / tex_size_div,
            0,
            PixelDataFormat::RGB,
            PixelDataType::UnsignedByte,
            nullptr);
    }
	void Render(double time)
	{
		gl.Clear().ColorBuffer().DepthBuffer();
		//
		auto camera = CamMatrixf::Orbiting(
			Vec3f(),
			4.5,
			Degrees(time * 35),
			Degrees(SineWave(time / 30.0) * 60)
		);

		auto model =
			ModelMatrixf::RotationY(FullCircles(time * 0.25)) *
			ModelMatrixf::RotationX(FullCircles(time * 0.33));

		camera_matrix.Set(camera);
		model_matrix.Set(model);
		transf_time.Set(time);

		face_pp.Bind();
		gl.PolygonMode(PolygonMode::Fill);
		torus_instr.Draw(torus_indices);

		frame_pp.Bind();
		gl.PolygonMode(PolygonMode::Line);
		torus_instr.Draw(torus_indices);
	}
	double Draw(double time)
	{
		assert(!shapes.empty());
		assert(ishape != shapes.end());
		shapes::ShapeWrapper& shape = *ishape;


		const double interval = 11.0;
		double segment = time - shape_time;
		double fade = segment*(interval-segment);
		fade -= 1.0;
		if(fade < 0.0) fade = 0.0;
		fade = std::sqrt(fade/interval);
		if(fade > 1.0) fade = 1.0;

		if(segment > interval)
		{
			if(++ishape == shapes.end())
			{
				ishape = shapes.begin();
			}
			shape_time = time;
		}

		gl.Clear().DepthBuffer();

		float dist = (1.0+SineWave(time / 13.0))*2.5;

		projection_matrix.Set(
			CamMatrixf::PerspectiveX(
				Degrees(45),
				1.0,
				1.0+dist,
				shape.BoundingSphere().Radius()*2.0+1.0+dist
			)
		);

		camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				shape.BoundingSphere().Radius()+1.5+dist,
				FullCircles(time / 27.0),
				Degrees(SineWave(time / 23.0) * 89)
			)
		);
		model_matrix.Set(
			ModelMatrixf::RotationA(
				Vec3f(1,1,1),
				FullCircles(time /-37.0)
			)
		);

		prog.Use();
		shape.Use();
		shape.Draw();

		return fade;
	}
Exemple #4
0
	void _use_font(const BitmapFontEssence& essence)
	{
		if(_prev_font_essence != static_cast<const void*>(&essence))
		{
			essence.Use();
			_bitmap_sampler.Set(GLint(essence.BitmapTexUnit()));
			_metric_sampler.Set(GLint(essence.MetricTexUnit()));
			_pg_map_sampler.Set(GLint(essence.PageMapTexUnit()));
			_prev_font_essence = &essence;
		}
	}
	void Reshape(GLuint width, GLuint height)
	{
		gl.Viewport(width, height);
		Mat4f projection = CamMatrixf::PerspectiveX(
			Degrees(65),
			double(width)/height,
			1, 40
		);
		norm_projection_matrix.Set(projection);
		refl_projection_matrix.Set(projection);
	}
void SRPWindows::DrawWindow()
{
	if (m_bInitialized && m_psWindowsData->bIsVisable) // should suffice
	{
		// set the program
		m_pCurrentRenderer->SetProgram(m_pProgramWrapper);
		// set the render state to allow for transparency
		m_pCurrentRenderer->SetRenderState(RenderState::BlendEnable, true);

		/*
		possible change
		- let (re)sizing be handled by the program uniform, see http://dev.pixellight.org/forum/viewtopic.php?f=6&t=503
		*/
		{
			const PLMath::Rectangle &cViewportRect = m_pCurrentRenderer->GetViewport();
			float fX1 = cViewportRect.vMin.x;
			float fY1 = cViewportRect.vMin.y;
			float fX2 = cViewportRect.vMax.x;
			float fY2 = cViewportRect.vMax.y;

			Matrix4x4 m_mObjectSpaceToClipSpace;
			m_mObjectSpaceToClipSpace.OrthoOffCenter(fX1, fX2, fY1, fY2, -1.0f, 1.0f);

			// create program uniform
			ProgramUniform *pProgramUniform = m_pProgramWrapper->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform)
				pProgramUniform->Set(m_mObjectSpaceToClipSpace);

			const int nTextureUnit = m_pProgramWrapper->Set("TextureMap", m_pTextureBuffer);
			if (nTextureUnit >= 0)
			{
				// set sampler states
				m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::AddressU, TextureAddressing::Clamp);
				m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::AddressV, TextureAddressing::Clamp);
				m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::None);
				m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::None);
				m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
			}

			// set vertex attributes
			m_pProgramWrapper->Set("VertexPosition", m_pVertexBuffer, VertexBuffer::Position);
			m_pProgramWrapper->Set("VertexTexCoord", m_pVertexBuffer, VertexBuffer::TexCoord);
		}

		// draw primitives
		m_pCurrentRenderer->DrawPrimitives(Primitive::TriangleStrip, 0, 4);
	}
}
Exemple #7
0
	void Render(const BitmapGlyphLayoutTpl<BitmapFont>& layout)
	{
		// we'll need the layout font's essence
		assert(layout._font._essence);
		// use the layout's font
		_use_font(*layout._font._essence);
		// use the layout's storage
		_use_layout(layout._data);

		// load the font pages referenced by the layout
		layout._font._essence->LoadPages(
			layout._pages.data(),
			layout._pages.size()
		);

		// set the Layout Width uniform value if necessary
		if(_layout_width_active)
			_layout_width.Set(layout._data._width);

		// draw the glyphs
		Context gl;
		gl.DrawArrays(
			PrimitiveType::Points,
			layout._data._offset,
			layout._data._length
		);
	}
	void Render(double time)
	{
		namespace se = oglplus::smart_enums;
		gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer();
		// make the camera matrix orbiting around the origin
		// at radius of 3.5 with elevation between 15 and 90 degrees
		Mat4f camera = CamMatrixf::Orbiting(
			Vec3f(),
			6.5,
			Degrees(time * 135),
			Degrees(15 + (-SineWave(0.25+time/12.5)+1.0)*0.5*75)
		);
		ModelMatrixf model = ModelMatrixf::Translation(0.0f, 1.5f, 0.0);
		ModelMatrixf identity;
		//
		norm_camera_matrix.Set(camera);
		refl_camera_matrix.Set(camera);
		// draw the plane into the stencil buffer
		prog_norm.Use();

		gl.Disable(se::Blend());
		gl.Disable(se::DepthTest());
		gl.Enable(se::StencilTest());
		gl.ColorMask(false, false, false, false);
		gl.StencilFunc(se::Always(), 1, 1);
		gl.StencilOp(se::Keep(), se::Keep(), se::Replace());

		norm_model_matrix.Set(identity);
		plane.Bind();
		gl.DrawArrays(se::TriangleStrip(), 0, 4);

		gl.ColorMask(true, true, true, true);
		gl.Enable(se::DepthTest());
		gl.StencilFunc(se::Equal(), 1, 1);
		gl.StencilOp(se::Keep(), se::Keep(), se::Keep());

		// draw the torus using the reflection program
		prog_refl.Use();
		refl_model_matrix.Set(model);
		torus.Bind();
		torus_instr.Draw(torus_indices);

		gl.Disable(se::StencilTest());

		prog_norm.Use();
		// draw the torus using the normal object program
		norm_model_matrix.Set(model);
		torus_instr.Draw(torus_indices);

		// blend-in the plane
		gl.Enable(se::Blend());
		gl.BlendEquation(se::Max());
		norm_model_matrix.Set(identity);
		plane.Bind();
		gl.DrawArrays(se::TriangleStrip(), 0, 4);
	}
    ReflectionExample()
      : make_plane(
          Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15)
      , plane_instr(make_plane.Instructions())
      , plane_indices(make_plane.Indices())
      , make_shape()
      , shape_instr(make_shape.Instructions())
      , shape_indices(make_shape.Indices())
      , plane_vs(ObjectDesc("Plane vertex"))
      , shape_vs(ObjectDesc("Shape vertex"))
      , plane_fs(ObjectDesc("Plane fragment"))
      , shape_fs(ObjectDesc("Shape fragment"))
      , plane_projection_matrix(plane_prog)
      , plane_camera_matrix(plane_prog)
      , plane_model_matrix(plane_prog)
      , shape_projection_matrix(shape_prog)
      , shape_camera_matrix(shape_prog)
      , shape_model_matrix(shape_prog)
      , width(800)
      , height(600)
      , tex_size_div(2) {
        plane_vs.Source(
          "#version 140\n"
          "uniform vec3 LightPosition;"
          "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;"
          "in vec4 Position;"
          "out vec3 vertLightDir;"
          "out vec4 vertTexCoord;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix*Position;"
          "	vertLightDir = LightPosition - gl_Position.xyz;"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "	vertTexCoord = gl_Position;"
          "}");
        plane_vs.Compile();

        plane_fs.Source(
          "#version 140\n"
          "uniform sampler2DRect ReflectTex;"
          "uniform vec3 Normal;"
          "in vec3 vertLightDir;"
          "in vec4 vertTexCoord;"
          "out vec3 fragColor;"
          "const int n = 5;"
          "const int ns = (n*n);"
          "const float blur = 0.15/n;"
          "void main()"
          "{"
          "	float d = dot(Normal, normalize(vertLightDir));"
          "	float intensity = 0.5 + pow(1.4*d, 2.0);"
          "	vec3 color = vec3(0.0, 0.0, 0.0);"
          "	int n = 2;"
          "	float pct = 0.5/vertTexCoord.w;"
          "	for(int y=-n; y!=(n+1); ++y)"
          "	for(int x=-n; x!=(n+1); ++x)"
          "	{"
          "		vec2 coord = vertTexCoord.xy;"
          "		coord += vec2(blur*x, blur*y);"
          "		coord *= pct;"
          "		coord += vec2(0.5, 0.5);"
          "		coord *= textureSize(ReflectTex);"
          "		color += texture(ReflectTex, coord).rgb/ns;"
          "	}"
          "	fragColor = color*intensity;"
          "}");
        plane_fs.Compile();

        plane_prog.AttachShader(plane_vs);
        plane_prog.AttachShader(plane_fs);
        plane_prog.Link();
        plane_prog.Use();

        plane_projection_matrix.BindTo("ProjectionMatrix");
        plane_camera_matrix.BindTo("CameraMatrix");
        plane_model_matrix.BindTo("ModelMatrix");

        Vec3f lightPos(3.0f, 0.5f, 2.0f);
        Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos);
        Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal());

        plane.Bind();

        plane_verts.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_plane.Positions(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(plane_prog, "Position");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }
        //
        Texture::Active(1);
        gl.Bound(Texture::Target::Rectangle, depth_tex)
          .MinFilter(TextureMinFilter::Linear)
          .MagFilter(TextureMagFilter::Linear)
          .WrapS(TextureWrap::ClampToEdge)
          .WrapT(TextureWrap::ClampToEdge);

        Texture::Active(0);
        ProgramUniformSampler(plane_prog, "ReflectTex").Set(0);
        gl.Bound(Texture::Target::Rectangle, reflect_tex)
          .MinFilter(TextureMinFilter::Linear)
          .MagFilter(TextureMagFilter::Linear)
          .WrapS(TextureWrap::ClampToEdge)
          .WrapT(TextureWrap::ClampToEdge);

        gl.Bound(Framebuffer::Target::Draw, fbo)
          .AttachTexture(FramebufferAttachment::Color, reflect_tex, 0)
          .AttachTexture(FramebufferAttachment::Depth, depth_tex, 0);

        shape_vs.Source(
          "#version 140\n"
          "uniform vec3 LightPosition;"
          "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;"
          "in vec4 Position;"
          "in vec3 Normal;"
          "out vec3 vertNormal;"
          "out vec3 vertLightDir;"
          "out vec3 vertLightRefl;"
          "out vec3 vertViewDir;"
          "out vec3 vertColor;"
          "void main()"
          "{"
          "	gl_Position = ModelMatrix * Position;"
          "	vertLightDir = LightPosition - gl_Position.xyz;"
          "	vertNormal = mat3(ModelMatrix)*Normal;"
          "	vertLightRefl = reflect("
          "		-normalize(vertLightDir),"
          "		normalize(vertNormal)"
          "	);"
          "	vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;"
          "	vertColor = vec3(1, 1, 1) - vertNormal;"
          "	gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;"
          "}");
        shape_vs.Compile();

        shape_fs.Source(
          "#version 140\n"
          "in vec3 vertNormal;"
          "in vec3 vertLightDir;"
          "in vec3 vertLightRefl;"
          "in vec3 vertViewDir;"
          "in vec3 vertColor;"
          "out vec3 fragColor;"

          "void main()"
          "{"
          "	float l = length(vertLightDir);"
          "	float d = dot("
          "		normalize(vertNormal), "
          "		normalize(vertLightDir)"
          "	) / l;"
          "	float s = dot("
          "		normalize(vertLightRefl),"
          "		normalize(vertViewDir)"
          "	);"
          "	vec3 lt = vec3(1.0, 1.0, 1.0);"
          "	fragColor = "
          "		vertColor * 0.4 + "
          "		(lt + vertColor)*pow(max(2.5*d, 0.0), 3) + "
          "		lt * pow(max(s, 0.0), 64);"
          "}");
        shape_fs.Compile();

        shape_prog.AttachShader(shape_vs);
        shape_prog.AttachShader(shape_fs);
        shape_prog.Link();
        shape_prog.Use();

        shape_projection_matrix.BindTo("ProjectionMatrix");
        shape_camera_matrix.BindTo("CameraMatrix");
        shape_model_matrix.BindTo("ModelMatrix");

        Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos);

        shape.Bind();

        shape_verts.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_shape.Positions(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(shape_prog, "Position");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }

        shape_normals.Bind(Buffer::Target::Array);
        {
            std::vector<GLfloat> data;
            GLuint n_per_vertex = make_shape.Normals(data);
            Buffer::Data(Buffer::Target::Array, data);
            VertexArrayAttrib attr(shape_prog, "Normal");
            attr.Setup<GLfloat>(n_per_vertex);
            attr.Enable();
        }
        //
        gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f);
        gl.ClearDepth(1.0f);
        gl.Enable(Capability::DepthTest);
        gl.Enable(Capability::CullFace);
    }
	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"))
	 , norm_projection_matrix(prog_norm)
	 , norm_camera_matrix(prog_norm)
	 , norm_model_matrix(prog_norm)
	 , refl_projection_matrix(prog_refl)
	 , refl_camera_matrix(prog_refl)
	 , refl_model_matrix(prog_refl)
	{
		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();

		norm_projection_matrix.BindTo("ProjectionMatrix");
		norm_camera_matrix.BindTo("CameraMatrix");
		norm_model_matrix.BindTo("ModelMatrix");

		// 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();

		refl_projection_matrix.BindTo("ProjectionMatrix");
		refl_camera_matrix.BindTo("CameraMatrix");
		refl_model_matrix.BindTo("ModelMatrix");

		// 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 VertexArrayAttrib VAA;
			VertexAttribSlot
				loc_norm = VAA::GetLocation(prog_norm, "Position"),
				loc_refl = VAA::GetLocation(prog_refl, "Position");

			assert(loc_norm == loc_refl);
			VertexArrayAttrib 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 VertexArrayAttrib VAA;
			VertexAttribSlot
				loc_norm = VAA::GetLocation(prog_norm, "Normal"),
				loc_refl = VAA::GetLocation(prog_refl, "Normal");

			assert(loc_norm == loc_refl);
			VertexArrayAttrib 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();
			VertexArrayAttrib 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();
			VertexArrayAttrib attr(prog_norm, "Normal");
			attr.Setup<Vec3f>();
			attr.Enable();
		}
		NoVertexArray().Bind();

		Vec3f lightPos(2.0f, 2.0f, 3.0f);
		prog_norm.Use();
		(prog_norm/"LightPos").Set(lightPos);
		prog_refl.Use();
		(prog_refl/"LightPos").Set(lightPos);
		//
		gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f);
		gl.ClearDepth(1.0f);
		gl.ClearStencil(0);
	}
Exemple #11
0
/**
*  @brief
*    Sets the value of this parameter to a parameter within the given manager GPU program
*/
bool Parameter::SetManagerParameterValue(Program &cProgram, const PLCore::String &sName) const
{
	// Get the GPU program uniform
	ProgramUniform *pProgramUniform = cProgram.GetUniform(sName);
	if (pProgramUniform) {
		// Set parameter
		switch (m_nType) {
			case Parameters::String:
				// GPU programs don't have string parameters
				break;

			case Parameters::Integer:
				pProgramUniform->Set(*static_cast<const int*>(m_pValue));
				break;

			case Parameters::Integer2:
				pProgramUniform->Set2(static_cast<const int*>(m_pValue));
				break;

			case Parameters::Integer3:
				pProgramUniform->Set3(static_cast<const int*>(m_pValue));
				break;

			case Parameters::Integer4:
				pProgramUniform->Set4(static_cast<const int*>(m_pValue));
				break;

			case Parameters::Float:
				pProgramUniform->Set(*static_cast<const float*>(m_pValue));
				break;

			case Parameters::Float2:
				pProgramUniform->Set2(static_cast<const float*>(m_pValue));
				break;

			case Parameters::Float3:
				pProgramUniform->Set3(static_cast<const float*>(m_pValue));
				break;

			case Parameters::Float4:
				pProgramUniform->Set4(static_cast<const float*>(m_pValue));
				break;

			case Parameters::Double:
				pProgramUniform->Set(*static_cast<const double*>(m_pValue));
				break;

			case Parameters::Double2:
				pProgramUniform->Set2(static_cast<const double*>(m_pValue));
				break;

			case Parameters::Double3:
				pProgramUniform->Set3(static_cast<const double*>(m_pValue));
				break;

			case Parameters::Double4:
				pProgramUniform->Set4(static_cast<const double*>(m_pValue));
				break;

			case Parameters::Float3x3:
				// [TODO] New shader interface: Add Set3x3 method?
				//pProgramUniform->Set(static_cast<const float*>(m_pValue));
				pProgramUniform->Set(Matrix3x3(static_cast<const float*>(m_pValue)));
				break;

			case Parameters::Float3x4:
				// [TODO] New shader interface: Add Set3x4 method?
				//pProgramUniform->Set(static_cast<const float*>(m_pValue));
				break;

			case Parameters::Float4x4:
				// [TODO] New shader interface: Add Set4x4 method?
				pProgramUniform->Set(Matrix4x4(static_cast<const float*>(m_pValue)));
				break;

			case Parameters::Double4x4:
				// [TODO] New shader interface: Add Set4x4 method?
				//pProgramUniform->Set(static_cast<const double*>(m_pValue));
				break;

			case Parameters::TextureBuffer:
				return false; // Error, not supported

			case Parameters::UnknownDataType:
			default:
				return false; // Error, not supported
		}

		// Done
		return true;
	}

	// Error!
	return false;
}
//[-------------------------------------------------------]
//[ Private virtual PLRenderer::SurfacePainter functions  ]
//[-------------------------------------------------------]
void SPRTTShaders::OnPaint(Surface &cSurface)
{
	// Get the used renderer
	Renderer &cRenderer = GetRenderer();

	// Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something)
	cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray);

	// Backup current render target and set the new one to render in our texture buffer
	Surface *pRenderSurfaceBackup = cRenderer.GetRenderTarget();
	if (cRenderer.SetRenderTarget(m_pRenderTarget)) {
		if (m_pColorTarget1)
			cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget1), 1);
		if (m_pColorTarget2)
			cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget2), 2);
		if (m_pColorTarget3)
			cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget3), 3);

		// Draw the scene
		DrawScene(cRenderer);

		// Reset render target
		cRenderer.SetRenderTarget(pRenderSurfaceBackup);
	}

	// This code is similar to the code of the triangle sample. But instead of a
	// triangle we will draw three rotating quadrangles. Further the used vertex
	// buffer has texture coordinates and we apply the 'teapot' texture buffer on the primitives.
	// Clear the content of the current used render target

	// Make our program to the current one
	if (cRenderer.SetProgram(m_pProgram)) {
		// Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute"
		m_pProgram->Set("VertexPosition",		   m_pPositionVertexBuffer, VertexBuffer::Position);
		m_pProgram->Set("VertexTextureCoordinate", m_pPositionVertexBuffer, VertexBuffer::TexCoord);
		m_pProgram->Set("VertexColor",			   m_pColorVertexBuffer,    VertexBuffer::Color);

		// Set color factor
		m_pProgram->Set("ColorFactor", 0.0f);

		// Calculate the composed view projection matrix - we need it multiple times
		Matrix4x4 mViewProjection;
		{
			// Calculate the view matrix
			Matrix4x4 mView;
			{
				mView.SetTranslation(0.0f, 0.0f, -5.0f);
			}

			// Calculate the projection matrix
			Matrix4x4 mProjection;
			{
				const float fAspect      = 1.0f;
				const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect);
				mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f);
			}

			// Calculate the composed view projection matrix
			mViewProjection = mProjection*mView;
		}

		// No back face culling, please. Else we can only see one 'side' of the quadrangle
		cRenderer.SetRenderState(RenderState::CullMode, Cull::None);

		Matrix4x4 mWorld;
		{ // Draw quadrangle 1: Primary render target
			// Set object space to clip space matrix uniform
			ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform) {
				mWorld.SetTranslationMatrix(2.0f, 1.0f, 0.0f);
				pProgramUniform->Set(mViewProjection*mWorld);
			}

			{ // Set the texture buffer we rendered our teapot in as the current texture buffer
				const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer());
				if (nTextureUnit >= 0) {
					// Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw
			cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4);
		}

		{ // Draw quadrangle 2: Color render target 1
			// Set object space to clip space matrix uniform
			ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform) {
				mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad));
				mWorld.SetTranslation(-2.0f, 1.0f, 0.0f);
				pProgramUniform->Set(mViewProjection*mWorld);
			}

			{ // Set the texture buffer we rendered our teapot in as the current texture buffer
				const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget1 ? static_cast<TextureBuffer*>(m_pColorTarget1) : m_pRenderTarget->GetTextureBuffer());
				if (nTextureUnit >= 0) {
					// Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw
			cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4);
		}

		{ // Draw quadrangle 3: Color render target 2
			// Set object space to clip space matrix uniform
			ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform) {
				mWorld.FromEulerAngleZ(static_cast<float>(m_fRotation*Math::DegToRad));
				mWorld.SetTranslation(0.0f, 1.0f, 0.0f);
				pProgramUniform->Set(mViewProjection*mWorld);
			}

			{ // Set the texture buffer we rendered our teapot in as the current texture buffer
				const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget2 ? static_cast<TextureBuffer*>(m_pColorTarget2) : m_pRenderTarget->GetTextureBuffer());
				if (nTextureUnit >= 0) {
					// Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw
			cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4);
		}

		{ // Draw quadrangle 4: Color render target 3
			// Set object space to clip space matrix uniform
			ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform) {
				mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad));
				mWorld.SetTranslation(-2.0f, -1.0f, 0.0f);
				pProgramUniform->Set(mViewProjection*mWorld);
			}

			{ // Set the texture buffer we rendered our teapot in as the current texture buffer
				const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget3 ? static_cast<TextureBuffer*>(m_pColorTarget3) : m_pRenderTarget->GetTextureBuffer());
				if (nTextureUnit >= 0) {
					// Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw
			cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4);
		}

		{ // Draw quadrangle 4: Primary render target, but with per vertex color - the primitive will be quite colorful :)
			// Set object space to clip space matrix uniform
			ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
			if (pProgramUniform) {
				mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad));
				mWorld.SetTranslation(2.0f, -1.0f, 0.0f);
				pProgramUniform->Set(mViewProjection*mWorld);
			}

			// Set color factor
			m_pProgram->Set("ColorFactor", 1.0f);

			{ // Set the texture buffer we rendered our teapot in as the current texture buffer
				const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer());
				if (nTextureUnit >= 0) {
					// Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear);
					cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw
			cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4);
		}

		// Change the backface culling back to the default setting
		cRenderer.SetRenderState(RenderState::CullMode, Cull::CCW);
	}

	// Increase the rotation by the current time difference (time past since the last frame)
	// -> Normally, such work should NOT be performed within the rendering step, but we want
	//    to keep the implementation simple in here...
	m_fRotation += Timing::GetInstance()->GetTimeDifference()*50;
}
/**
*  @brief
*    Draws the scene
*/
void SPRTTShaders::DrawScene(Renderer &cRenderer)
{
	// Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something)
	cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray);

	// Make our program to the current one
	if (cRenderer.SetProgram(m_pSceneProgram)) {
		// Calculate the world matrix
		Matrix4x4 mWorld;
		{
			// Build a rotation matrix by using a given Euler angle around the y-axis
			mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad));
		}

		// Set program uniforms
		ProgramUniform *pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToClipSpaceMatrix");
		if (pProgramUniform) {
			// Calculate the view matrix
			Matrix4x4 mView;
			{
				mView.SetTranslation(0.0f, -0.1f, -0.5f);
			}

			// Calculate the projection matrix
			Matrix4x4 mProjection;
			{
				const float fAspect      = 1.0f;
				const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect);
				mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f);
			}

			// Calculate the final composed world view projection matrix
			const Matrix4x4 mWorldViewProjection = mProjection*mView*mWorld;

			// Set object space to clip space matrix uniform
			pProgramUniform->Set(mWorldViewProjection);
		}

		// Set object space to world space matrix uniform
		pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToWorldSpaceMatrix");
		if (pProgramUniform)
			pProgramUniform->Set(mWorld);

		// Set world space light direction
		pProgramUniform = m_pSceneProgram->GetUniform("LightDirection");
		if (pProgramUniform)
			pProgramUniform->Set(Vector3::UnitZ);

		// Get the used mesh
		const Mesh *pMesh = m_pMeshHandler->GetMesh();
		if (pMesh) {
			// Get the mesh LOD level to use
			const MeshLODLevel *pLODLevel = pMesh->GetLODLevel(0);
			if (pLODLevel && pLODLevel->GetIndexBuffer()) {
				// Get and use the index buffer of the mesh LOD level
				cRenderer.SetIndexBuffer(pLODLevel->GetIndexBuffer());

				// Get the vertex buffer of the mesh handler
				VertexBuffer *pVertexBuffer = m_pMeshHandler->GetVertexBuffer();
				if (pVertexBuffer) {
					// Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute"
					ProgramAttribute *pProgramAttribute = m_pSceneProgram->GetAttribute("VertexPosition");
					if (pProgramAttribute)
						pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Position);
					pProgramAttribute = m_pSceneProgram->GetAttribute("VertexNormal");
					if (pProgramAttribute)
						pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Normal);

					// Loop through all geometries of the mesh
					const Array<Geometry> &lstGeometries = *pLODLevel->GetGeometries();
					for (uint32 nGeo=0; nGeo<lstGeometries.GetNumOfElements(); nGeo++) {
						// Is this geometry active?
						const Geometry &cGeometry = lstGeometries[nGeo];
						if (cGeometry.IsActive()) {
							// Draw the geometry
							cRenderer.DrawIndexedPrimitives(
								cGeometry.GetPrimitiveType(),
								0,
								pVertexBuffer->GetNumOfElements()-1,
								cGeometry.GetStartIndex(),
								cGeometry.GetIndexSize()
							);
						}
					}
				}
			}
		}
	}
}