235 lines
6.9 KiB
C++
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);
|
|
}
|
|
//------------------------------------------------------------------------------
|