Files
Webcam/include/engine/gpu/gpu_helper.cpp

235 lines
6.9 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "gpu/gpu_types.h"
#include "gpu/gpu_renderer.h"
#include "log/log.h"
using namespace GS;
using namespace GS::GPU;
/*
0 - - 3
| |
| |
1 - - 2
*/
//------------------------------------------------------------------------------
bool Renderer::BuildDirectVertexLayout(uint idx_count, const ushort *idx, const Vector4 *v, const Color *c, const Vector2 *uv, DirectVertexLayout &layout, VBO *idx_vbo, VBO *vtx_vbo)
{
if (idx_vbo)
{
size_t size = idx_count * sizeof(ushort);
if (size > idx_vbo->GetSize())
if (!idx_vbo->Create(size, VBO::Index, VBO::Dynamic))
return false;
if (void *p = idx_vbo->Map())
{
Memory::Copy(p, idx, size);
idx_vbo->Unmap();
}
}
// Find vertex count.
ushort vtx_count = 0;
for (uint n = 0; n < idx_count; ++n)
vtx_count = GS::Types::Max(vtx_count, idx[n]);
++vtx_count;
// Build layout.
layout.stride = 0;
if (v)
{
layout.vtx_offset = layout.stride;
layout.stride += 3 * sizeof(float);
}
if (c)
{
layout.color_offset = layout.stride;
layout.stride += 4 * sizeof(uchar);
}
if (uv)
{
layout.uv_offset = layout.stride;
layout.stride += 2 * sizeof(float);
}
// Build interleaved vertex data.
if (vtx_vbo)
{
size_t size = vtx_count * layout.stride;
if (size > vtx_vbo->GetSize())
if (!vtx_vbo->Create(size, VBO::Vertex, VBO::Dynamic))
return false;
if (char *p_data = (char *)vtx_vbo->Map())
{
for (uint n = 0; n < vtx_count; ++n)
{
if (v)
{
float *p_vtx = (float *)(p_data + layout.vtx_offset);
p_vtx[0] = v[n].x;
p_vtx[1] = v[n].y;
p_vtx[2] = v[n].z;
}
if (c)
{
uchar *p_color = (uchar *)(p_data + layout.color_offset);
p_color[0] = uchar(c[n].x * 255.f);
p_color[1] = uchar(c[n].y * 255.f);
p_color[2] = uchar(c[n].z * 255.f);
p_color[3] = uchar(c[n].w * 255.f);
}
if (uv)
{
float *p_uv = (float *)(p_data + layout.uv_offset);
p_uv[0] = uv[n].x;
p_uv[1] = uv[n].y;
}
p_data += layout.stride;
}
vtx_vbo->Unmap();
}
}
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Renderer::RenderFullscreenQuad(Shader &p, float k_x, float k_y, Render::Texture *t, Core::Light *l)
{
__NTRACE("RenderFullscreenQuad")
const size_t stride = sizeof(float) * 5;
if (gpu_config.tex_origin_is_top_left)
{
const float vtx[] = { -1, 1, 1, 0, k_y, -1, -1, 1, 0, 0, 1, -1, 1, k_x, 0, 1, 1, 1, k_x, k_y };
helper_vtx_vbo->Update(vtx, 0, stride * 4);
}
else
{
const float vtx[] = { -1, 1, 1, 0, 1.f - k_y, -1, -1, 1, 0, 1, 1, -1, 1, k_x, 1, 1, 1, 1, k_x, 1.f - k_y };
helper_vtx_vbo->Update(vtx, 0, stride * 4);
}
SetDepthFunc(DepthAlways);
EnableDepthWrite(false);
SetShaderProgram(&p);
SetIndexSource(helper_idx_vbo);
SetVertexSource(helper_vtx_vbo, sizeof(float) * 5);
ShaderInput *vtx_parm = p.GetInput(Core::ShaderInput::Position),
*uv_parm = p.GetInput(Core::ShaderInput::UV0),
*texture_parm = p.GetInput(Core::ShaderInput::Texture2D);
if (!texture_parm) // get cube map (TEMP HACK)
texture_parm = p.GetInput(Core::ShaderInput::TextureCube);
if (vtx_parm)
p.Set(*vtx_parm->location, 3, Types::ValueFloat, false, stride, (const void *)0);
if (uv_parm)
p.Set(*uv_parm->location, 2, Types::ValueFloat, false, stride, (const void *)(sizeof(float) * 3));
if (texture_parm && t)
texture_parm->SetValue(t);
if (view_item && l)
p.SetLightInputs(*this, *view_item, *l);
p.SetTransformInputs(Matrix4::IdentityMatrix(), Matrix4::IdentityMatrix(), Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
p.SetRendererInputs(*this);
p.SetConstantInputs();
p.SetTextureInputs();
p.CommitInputs();
DrawElements(Types::PrimitiveTriangle, 3 * 2, Types::ValueUShort);
if (vtx_parm)
p.Set(*vtx_parm->location, 0, Types::ValueLast, false, 0, NULL);
if (uv_parm)
p.Set(*uv_parm->location, 0, Types::ValueLast, false, 0, NULL);
EnableDepthWrite(true);
SetDepthFunc(DepthLess);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Renderer::RenderFullscreenQuad(Shader &p, const fRect &src_rect, const fRect &dst_rect, Render::Texture *t, Core::Light *l)
{
__NTRACE("RenderFullscreenQuad (Region)")
const size_t stride = sizeof(float) * 5;
if (gpu_config.tex_origin_is_top_left)
{
const float vtx[] =
{
dst_rect.sx * 2.f - 1.f, dst_rect.sy * 2.f - 1.f, 1, src_rect.sx, src_rect.sy,
dst_rect.ex * 2.f - 1.f, dst_rect.sy * 2.f - 1.f, 1, src_rect.ex, src_rect.sy,
dst_rect.ex * 2.f - 1.f, dst_rect.ey * 2.f - 1.f, 1, src_rect.ex, src_rect.ey,
dst_rect.sx * 2.f - 1.f, dst_rect.ey * 2.f - 1.f, 1, src_rect.sx, src_rect.ey
};
helper_vtx_vbo->Update(vtx, 0, stride * 4);
}
else
{
const float vtx[] =
{
dst_rect.sx * 2.f - 1.f, dst_rect.sy * 2.f - 1.f, 1, src_rect.sx, src_rect.ey,
dst_rect.ex * 2.f - 1.f, dst_rect.sy * 2.f - 1.f, 1, src_rect.ex, src_rect.ey,
dst_rect.ex * 2.f - 1.f, dst_rect.ey * 2.f - 1.f, 1, src_rect.ex, src_rect.sy,
dst_rect.sx * 2.f - 1.f, dst_rect.ey * 2.f - 1.f, 1, src_rect.sx, src_rect.sy
};
helper_vtx_vbo->Update(vtx, 0, stride * 4);
}
SetDepthFunc(DepthAlways);
EnableDepthWrite(false);
SetShaderProgram(&p);
SetIndexSource(helper_idx_vbo);
SetVertexSource(helper_vtx_vbo, stride);
ShaderInput *vtx_parm = p.GetInput(Core::ShaderInput::Position),
*uv_parm = p.GetInput(Core::ShaderInput::UV0),
*texture_parm = p.GetInput(Core::ShaderInput::Texture2D);
if (!texture_parm) // get cube map (TEMP HACK)
texture_parm = p.GetInput(Core::ShaderInput::TextureCube);
if (vtx_parm)
p.Set(*vtx_parm->location, 3, Types::ValueFloat, false, stride, (const void *)0);
if (uv_parm)
p.Set(*uv_parm->location, 2, Types::ValueFloat, false, stride, (const void *)(sizeof(float) * 3));
if (texture_parm && t)
texture_parm->SetValue(t);
if (view_item && l)
p.SetLightInputs(*this, *view_item, *l);
p.SetTransformInputs(Matrix4::IdentityMatrix(), Matrix4::IdentityMatrix(), Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
p.SetRendererInputs(*this);
p.SetConstantInputs();
p.SetTextureInputs();
p.CommitInputs();
DrawElements(Types::PrimitiveTriangle, 3 * 2, Types::ValueUShort);
if (vtx_parm)
p.Set(*vtx_parm->location, 0, Types::ValueLast, false, 0, NULL);
if (uv_parm)
p.Set(*uv_parm->location, 0, Types::ValueLast, false, 0, NULL);
EnableDepthWrite(true);
SetDepthFunc(DepthLess);
}
//------------------------------------------------------------------------------