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