111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri/**************************************************************************
211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri *
311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * Copyright 2010 Luca Barbieri
411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri *
511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * Permission is hereby granted, free of charge, to any person obtaining
611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * a copy of this software and associated documentation files (the
711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * "Software"), to deal in the Software without restriction, including
811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * distribute, sublicense, and/or sell copies of the Software, and to
1011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * permit persons to whom the Software is furnished to do so, subject to
1111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * the following conditions:
1211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri *
1311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * The above copyright notice and this permission notice (including the
1411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * next paragraph) shall be included in all copies or substantial
1511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * portions of the Software.
1611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri *
1711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
2111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri *
2511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri **************************************************************************/
2611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
2711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri#include <vector>
2811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
2911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri#include "d3d11blit.hlsl.ps.h"
3011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri#include "d3d11blit.hlsl.vs.h"
3111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
3211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename index_type = unsigned>
3311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieristruct triangle_list_indices : public std::vector<index_type>
3411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
3511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned base;
3611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	bool flip;
3711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
3811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	triangle_list_indices()
3911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	: base(0), flip(false)
4011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{}
4111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
4211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c)
4311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
4411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		this->push_back(base + a);
4511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		this->push_back(base + (flip ? c : b));
4611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		this->push_back(base + (flip ? b : c));
4711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
4811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
4911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c, unsigned d)
5011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
5111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, b, c);
5211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, c, d);
5311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
5411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
5511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c, unsigned d, unsigned e)
5611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
5711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, b, c, d);
5811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, d, e);
5911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
6011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
6111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f)
6211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
6311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, b, c, d, e);
6411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, e, f);
6511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
6611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
6711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g)
6811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
6911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, b, c, d, e, f);
7011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, f, g);
7111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
7211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
7311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void poly(unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g, unsigned h)
7411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
7511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, b, c, d, e, f, g);
7611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		poly(a, g, h);
7711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
7811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri};
7911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
8011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieristruct mesh
8111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
8211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	ID3D11InputLayout* layout;
8311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	ID3D11Buffer* buffer;
8411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	D3D11_PRIMITIVE_TOPOLOGY topology;
8511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned vertex_size;
8611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned draw_count;
8711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	DXGI_FORMAT index_format;
8811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned index_offset;
8911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
9011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mesh(ID3D11Device* dev, D3D11_PRIMITIVE_TOPOLOGY topology,
9111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		const D3D11_INPUT_ELEMENT_DESC *elements, unsigned num_elements,
9211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		const void* vs, unsigned vs_size,
9311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		const void* vertices, unsigned vertex_size, unsigned num_vertices,
9411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		const void* indices = 0, unsigned index_size = 0, unsigned num_indices = 0)
9511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		: topology(topology), vertex_size(vertex_size), draw_count(index_size ? num_indices : num_vertices)
9611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
9711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		dev->CreateInputLayout(elements, num_elements, vs, vs_size, &layout);
9811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		if(index_size == 2)
9911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			index_format = DXGI_FORMAT_R16_UINT;
10011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		else if(index_size == 4)
10111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			index_format = DXGI_FORMAT_R32_UINT;
10211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		else
10311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			index_format = DXGI_FORMAT_UNKNOWN;
10411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		this->vertex_size = vertex_size;
10511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		index_offset = vertex_size * num_vertices;
10611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
10711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	 	D3D11_BUFFER_DESC bufferd;
10811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		memset(&bufferd, 0, sizeof(bufferd));
10911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		bufferd.Usage = D3D11_USAGE_IMMUTABLE;
11011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		bufferd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
11111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		if(index_format)
11211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			bufferd.BindFlags |= D3D11_BIND_INDEX_BUFFER;
11311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		bufferd.ByteWidth = index_offset + index_format * num_indices;
11411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
11511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		char* data = (char*)malloc(bufferd.ByteWidth);
11611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		memcpy(data, vertices, vertex_size * num_vertices);
11711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		memcpy(data + index_offset, indices, index_size * num_indices);
11811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
11911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		D3D11_SUBRESOURCE_DATA buffersd;
12011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		buffersd.pSysMem = data;
12111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
12211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ensure(dev->CreateBuffer(&bufferd, &buffersd, &buffer));
12311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		free(data);
12411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
12511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
12611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	~mesh()
12711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
12811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		layout->Release();
12911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		buffer->Release();
13011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
13111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
13211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void bind(ID3D11DeviceContext* ctx)
13311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
13411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		unsigned offset = 0;
13511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->IASetPrimitiveTopology(topology);
13611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->IASetInputLayout(layout);
13711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		if(index_format)
13811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			ctx->IASetIndexBuffer(buffer, index_format, index_offset);
13911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->IASetVertexBuffers(0, 1, &buffer, &vertex_size, &offset);
14011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
14111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
14211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void draw_bound(ID3D11DeviceContext* ctx)
14311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
14411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		if(index_format)
14511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			ctx->DrawIndexed(draw_count, 0, 0);
14611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		else
14711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			ctx->Draw(draw_count, 0);
14811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
14911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
15011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void bind_and_draw(ID3D11DeviceContext* ctx)
15111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
15211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		bind(ctx);
15311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		draw_bound(ctx);
15411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
15511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri};
15611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
15711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimesh* create_tex_quad(ID3D11Device* dev, const BYTE* vs, unsigned vs_size)
15811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
15911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	float quad_data[] = {
16011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		-1, -1, 0, 1,
16111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		-1, 1, 0, 0,
16211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		1, -1, 1, 1,
16311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		1, 1, 1, 0,
16411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	};
16511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
16611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	D3D11_INPUT_ELEMENT_DESC elements[2] =
16711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
16811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
16911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
17011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	};
17111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
17211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return new mesh(dev, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
17311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		elements, 2,
17411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vs, vs_size,
17511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		quad_data, 4 * sizeof(float), 4,
17611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		0, 0, 0);
17711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
17811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
17911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieristruct d3d11_blitter
18011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
18111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mesh* quad;
18211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	ID3D11VertexShader* vs;
18311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	ID3D11PixelShader* ps;
18411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	ID3D11SamplerState* sampler[2];
18511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
18611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	d3d11_blitter(ID3D11Device* dev)
18711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
18811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		quad = create_tex_quad(dev, g_vs_blit, sizeof(g_vs_blit));
18911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
19011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		dev->CreateVertexShader(g_vs_blit, sizeof(g_vs_blit), 0, &vs);
19111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		dev->CreatePixelShader(g_ps_blit, sizeof(g_ps_blit), 0, &ps);
19211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
19311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		for(unsigned i = 0; i < 2; ++i)
19411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		{
19511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			D3D11_SAMPLER_DESC samplerd;
19611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			memset(&samplerd, 0, sizeof(samplerd));
19711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			samplerd.Filter = i ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
19811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			samplerd.AddressU = samplerd.AddressV = samplerd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
19911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri			dev->CreateSamplerState(&samplerd, &sampler[i]);
20011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		}
20111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
20211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
20311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void bind(ID3D11DeviceContext* ctx, ID3D11ShaderResourceView* srv, ID3D11RenderTargetView* rtv, float x, float y, float width, float height, bool linear)
20411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
20511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		D3D11_VIEWPORT vp;
20611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.TopLeftX = x;
20711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.TopLeftY = y;
20811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.Width = width;
20911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.Height = height;
21011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.MinDepth = 0;
21111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		vp.MaxDepth = 1;
21211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->RSSetViewports(1, &vp);
21311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->RSSetState(0);
21411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->OMSetBlendState(0, 0, ~0);
21511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->OMSetDepthStencilState(0, 0);
21611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->OMSetRenderTargets(1, &rtv, 0);
21711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->VSSetShader(vs, 0, 0);
21811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->PSSetShader(ps, 0, 0);
21911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->PSSetShaderResources(0, 1, &srv);
22011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->PSSetSamplers(0, 1, &sampler[!!linear]);
22111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		quad->bind(ctx);
22211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
22311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
22411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void draw_bound(ID3D11DeviceContext* ctx)
22511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
22611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		quad->draw_bound(ctx);
22711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
22811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
22911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void bind_draw_and_unbind(ID3D11DeviceContext* ctx, ID3D11ShaderResourceView* srv, ID3D11RenderTargetView* rtv, float x, float y, float width, float height, bool linear)
23011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
23111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		bind(ctx, srv, rtv, x, y, width, height, linear);
23211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		draw_bound(ctx);
23311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		unbind(ctx);
23411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
23511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
23611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	void unbind(ID3D11DeviceContext* ctx)
23711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
23811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		void* null = 0;
23911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&null);
24011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		ctx->PSSetSamplers(0, 1, (ID3D11SamplerState**)&null);
24111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
24211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri};
24311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
24411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
24511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieristruct vec_t
24611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
24711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T v[n];
24811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
24911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T& operator [](unsigned i)
25011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
25111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		return v[i];
25211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
25311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
25411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	const T& operator [](unsigned i) const
25511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	{
25611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		return v[i];
25711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	}
25811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri};
25911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
26011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
26111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, n> operator -(const vec_t<T, n> a)
26211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
26311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, n> r;
26411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < n; ++i)
26511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r[i] = -a[i];
26611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
26711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
26811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
26911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
27011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, n> operator +(const vec_t<T, n>& a, const vec_t<T, n>& b)
27111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
27211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, n> r;
27311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < n; ++i)
27411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r[i] = a[i] + b[i];
27511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
27611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
27711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
27811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
27911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, n>& operator +=(vec_t<T, n>& a, const vec_t<T, n>& b)
28011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
28111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < n; ++i)
28211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		a[i] += b[i];
28311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return a;
28411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
28511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
28611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned r, unsigned c>
28711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieristruct mat_t : public vec_t<vec_t<T, r>, c>
28811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{};
28911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
29011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
29111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, n> operator *(const vec_t<T, n>& a, const T& b)
29211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
29311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, n> r;
29411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < n; ++i)
29511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r[i] = a[i] * b;
29611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
29711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
29811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
29911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
30011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, n> operator *(const T& b, const vec_t<T, n>& a)
30111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
30211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, n> r;
30311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < n; ++i)
30411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r[i] = a[i] * b;
30511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
30611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
30711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
30811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned d, unsigned e>
30911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, e> operator *(const mat_t<T, e, d>& m, const vec_t<T, d>& b)
31011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
31111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, e> r;
31211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	r = m[0] * b[0];
31311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 1; i < d; ++i)
31411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r += m[i] * b[i];
31511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
31611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
31711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
31811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned d, unsigned e, unsigned f>
31911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, e, f> operator *(const mat_t<T, e, d>& m, const mat_t<T, d, f>& b)
32011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
32111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, e, f> r;
32211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	for(unsigned i = 0; i < d; ++i)
32311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		r[i] = m * b[i];
32411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
32511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
32611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
32711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T>
32811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, 3> vec(T a, T b, T c)
32911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
33011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, 4> v;
33111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[0] = a;
33211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[1] = b;
33311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[2] = c;
33411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return v;
33511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
33611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
33711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T>
33811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierivec_t<T, 4> vec(T a, T b, T c, T d)
33911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
34011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, 4> v;
34111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[0] = a;
34211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[1] = b;
34311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[2] = c;
34411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[3] = d;
34511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return v;
34611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
34711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
34811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef mat_t<float, 4, 4> float4x4;
34911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef mat_t<float, 4, 3> float4x3;
35011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef mat_t<float, 3, 4> float3x4;
35111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef mat_t<float, 3, 3> float3x3;
35211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
35311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef vec_t<float, 3> float3;
35411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritypedef vec_t<float, 4> float4;
35511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
35611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T>
35711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, 4, 4> mat4x4_frustum(T left, T right, T bottom, T top, T nearval, T farval)
35811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
35911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T x = (2.0f * nearval) / (right - left);
36011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T y = (2.0f * nearval) / (top - bottom);
36111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T a = (right + left) / (right - left);
36211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T b = (top + bottom) / (top - bottom);
36311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T c = -(farval + nearval) / (farval - nearval);
36411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T d = -(2.0f * farval * nearval) / (farval - nearval);
36511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T _0 = (T)0;
36611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
36711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, 4, 4> m;
36811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[0] = vec(x, _0, _0, _0);
36911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[1] = vec(_0, y, _0, _0);
37011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[2] = vec(a, b, c, (T)-1);
37111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[3] = vec(_0, _0, d, _0);
37211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return m;
37311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
37411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
37511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T>
37611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, 3, 3> mat3x3_diag(T v)
37711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
37811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, 3, 3> m;
37911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T _0 = (T)0;
38011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[0] = vec(v, _0, _0);
38111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[1] = vec(_0, v, _0);
38211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[2] = vec(_0, _0, v);
38311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return m;
38411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
38511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
38611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T>
38711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, 4, 4> mat4x4_diag(T v)
38811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
38911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, 4, 4> m;
39011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T _0 = (T)0;
39111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[0] = vec(v, _0, _0, _0);
39211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[1] = vec(_0, v, _0, _0);
39311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[2] = vec(_0, _0, v, _0);
39411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	m[3] = vec(_0, _0, _0, v);
39511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return m;
39611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
39711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
39811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
39911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, n, n> mat_push_rotate(const mat_t<T, n, n>& m, unsigned axis, T angle)
40011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
40111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T s = (T)sin(angle);
40211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	T c = (T)cos(angle);
40311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
40411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, n, n> r = m;
40511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned a = (axis + 1) % 3;
40611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	unsigned b = (axis + 2) % 3;
40711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	r[a] = (m[a] * c) + (m[b] * s);
40811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	r[b] = -(m[a] * s) + (m[b] * c);
40911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
41011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
41111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri
41211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieritemplate<typename T, unsigned n>
41311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbierimat_t<T, n, n> mat_push_translate(const mat_t<T, n, n>& m, float x, float y, float z)
41411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri{
41511547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	mat_t<T, n, n> r = m;
41611547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	vec_t<T, n> v;
41711547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[0] = x;
41811547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[1] = y;
41911547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	v[2] = z;
42011547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	if(n >= 4)
42111547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri		v[3] = (T)0;
42211547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	r[3] += m * v;
42311547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri	return r;
42411547654295cadcfde69f6c2361f50a4cd17fc7aLuca Barbieri}
425