/* ----------------------------------------------------------------------------- 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); } //------------------------------------------------------------------------------