first commit
This commit is contained in:
40
include/engine/gpu/gpu_caps.h
Normal file
40
include/engine/gpu/gpu_caps.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUCAPS__
|
||||
#define __GPUCAPS__
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
enum Caps
|
||||
{
|
||||
/*!
|
||||
@name Hardware caps.
|
||||
@{
|
||||
*/
|
||||
MaxTextureSize,
|
||||
MaxTextureUnit,
|
||||
|
||||
CanBlitRBO,
|
||||
TextureTopLeftOrigin,
|
||||
|
||||
MaxAnisotropy,
|
||||
/*!
|
||||
@}
|
||||
@name Performance hints.
|
||||
@{
|
||||
*/
|
||||
CheapLights
|
||||
/// @}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUCAPS__
|
||||
64
include/engine/gpu/gpu_config.h
Normal file
64
include/engine/gpu/gpu_config.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUCONFIG__
|
||||
#define __GPUCONFIG__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
struct RendererConfig
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
enum NPOTSupport
|
||||
{
|
||||
NPOT_None = 0,
|
||||
NPOT_Limited, // NPOT support with no mipmap and wrap as clamp to edge only.
|
||||
NPOT_Full
|
||||
};
|
||||
|
||||
uint npot;
|
||||
uint shadow_size;
|
||||
uint max_anisotropy;
|
||||
|
||||
bool use_rtt;
|
||||
|
||||
bool can_resolve_msaa;
|
||||
bool can_stream_vertex_from_memory;
|
||||
|
||||
bool enable_aa;
|
||||
bool enable_shadow;
|
||||
bool tex_origin_is_top_left;
|
||||
|
||||
RendererConfig()
|
||||
{
|
||||
npot = NPOT_Full;
|
||||
shadow_size = 1024;
|
||||
max_anisotropy = 1;
|
||||
|
||||
use_rtt = true;
|
||||
|
||||
can_resolve_msaa = true;
|
||||
can_stream_vertex_from_memory = true;
|
||||
|
||||
enable_aa = false;
|
||||
enable_shadow = true;
|
||||
|
||||
tex_origin_is_top_left = true;
|
||||
}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUCONFIG__
|
||||
113
include/engine/gpu/gpu_display_list.h
Normal file
113
include/engine/gpu/gpu_display_list.h
Normal file
@ -0,0 +1,113 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUDISPLAYLIST__
|
||||
#define __GPUDISPLAYLIST__
|
||||
|
||||
|
||||
#include "gpu/gpu_vbo.h"
|
||||
#include "core/render_data.h"
|
||||
#include "memory/nauto_ptr.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
namespace Core {
|
||||
struct Trilist;
|
||||
struct Patch;
|
||||
class Emitter;
|
||||
class Item;
|
||||
}
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
|
||||
//
|
||||
struct DisplayList
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
Renderer &renderer;
|
||||
|
||||
AutoPtr <VBO> idx, vtx;
|
||||
Array <ushort> idx_map;
|
||||
Array <char> vtx_map;
|
||||
size_t stride;
|
||||
|
||||
MinMax minmax;
|
||||
|
||||
uint index_count;
|
||||
|
||||
size_t vertex_offset,
|
||||
normal_offset,
|
||||
rgb_offset,
|
||||
uv_offset[__UV_PER_GEOMETRY__],
|
||||
tangent_offset,
|
||||
skinning_offset;
|
||||
|
||||
Array <ushort> bone;
|
||||
|
||||
Render::sMaterial material;
|
||||
|
||||
/// Create display list from a triangle list.
|
||||
virtual bool Create(Core::Trilist *, Render::Material *);
|
||||
/// Draw display list.
|
||||
virtual void Draw() = 0;
|
||||
|
||||
DisplayList(Renderer &r) : renderer(r)
|
||||
{
|
||||
idx = 0;
|
||||
vtx = 0;
|
||||
|
||||
index_count = 0;
|
||||
|
||||
vertex_offset = (size_t)-1;
|
||||
normal_offset = (size_t)-1;
|
||||
rgb_offset = (size_t)-1;
|
||||
for (uint n = 0; n < __UV_PER_GEOMETRY__; ++n)
|
||||
uv_offset[n] = (size_t)-1;
|
||||
tangent_offset = (size_t)-1;
|
||||
skinning_offset = (size_t)-1;
|
||||
|
||||
stride = 0;
|
||||
}
|
||||
virtual ~DisplayList() {}
|
||||
};
|
||||
|
||||
//
|
||||
struct RenderPrimitive
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
enum Type
|
||||
{
|
||||
TypeDisplayList = 0,
|
||||
TypeEmitter,
|
||||
TypeTerrainPatch
|
||||
};
|
||||
|
||||
Type type;
|
||||
const Core::Item *item;
|
||||
|
||||
union
|
||||
{
|
||||
DisplayList *dlst;
|
||||
Core::Emitter *emitter;
|
||||
Core::Patch *patch;
|
||||
};
|
||||
|
||||
bool operator == (const RenderPrimitive &b)
|
||||
{ return (type == b.type) && (item == b.item) && (dlst == b.dlst); }
|
||||
|
||||
RenderPrimitive(const Core::Item *i, DisplayList *d) : type(TypeDisplayList), item(i), dlst(d) {}
|
||||
RenderPrimitive(const Core::Item *i, Core::Emitter *e) : type(TypeEmitter), item(i), emitter(e) {}
|
||||
RenderPrimitive(const Core::Item *i, Core::Patch *p) : type(TypeTerrainPatch), item(i), patch(p) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUDISPLAYLIST__
|
||||
65
include/engine/gpu/gpu_draw_context.h
Normal file
65
include/engine/gpu/gpu_draw_context.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUDRAWCONTEXT__
|
||||
#define __GPUDRAWCONTEXT__
|
||||
|
||||
|
||||
#include "gpu/gpu_material.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
namespace Core { class Light; }
|
||||
namespace GPU {
|
||||
|
||||
//
|
||||
struct DrawContext
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
enum Render
|
||||
{
|
||||
Deferred = 0,
|
||||
Opaque,
|
||||
Alpha
|
||||
};
|
||||
enum Draw
|
||||
{
|
||||
Base = 0,
|
||||
Light
|
||||
};
|
||||
|
||||
struct Context
|
||||
{
|
||||
Draw draw;
|
||||
Render render;
|
||||
MaterialShader::Variant variant;
|
||||
};
|
||||
|
||||
Context ctx;
|
||||
|
||||
Core::Light *light;
|
||||
|
||||
void SetContext(Render rc, Draw dc, MaterialShader::Variant prg)
|
||||
{
|
||||
ctx.render = rc;
|
||||
ctx.draw = dc;
|
||||
ctx.variant = prg;
|
||||
}
|
||||
|
||||
DrawContext(Render rc, Draw dc, MaterialShader::Variant prg = MaterialShader::Depth)
|
||||
{
|
||||
SetContext(rc, dc, prg);
|
||||
light = 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUDRAWCONTEXT__
|
||||
75
include/engine/gpu/gpu_fbo.h
Normal file
75
include/engine/gpu/gpu_fbo.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUFBO__
|
||||
#define __GPUFBO__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
#include "geometry/rect.h"
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace Render { struct Texture; }
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
|
||||
/*!
|
||||
@short GPU frame buffer object.
|
||||
@author Emmanuel Julien (ejulien@nworks.fr)
|
||||
*/
|
||||
struct FBO
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
Renderer &renderer;
|
||||
|
||||
uint color_texture_count;
|
||||
|
||||
Render::Texture *color_texture[8], *depth_texture;
|
||||
|
||||
/// Set output color texture.
|
||||
virtual void SetColorTexture(Render::Texture *t)
|
||||
{
|
||||
color_texture[0] = t;
|
||||
color_texture_count = 1;
|
||||
}
|
||||
/// Set output color texture.
|
||||
virtual void SetColorTexture(Render::Texture *t[], uint n)
|
||||
{
|
||||
for (color_texture_count = 0; color_texture_count < n; ++color_texture_count)
|
||||
color_texture[color_texture_count] = t[color_texture_count];
|
||||
}
|
||||
/// Set output depth texture.
|
||||
virtual void SetDepthTexture(Render::Texture *t)
|
||||
{ depth_texture = t; }
|
||||
|
||||
/// Blit attachment to another FBO attachment.
|
||||
virtual void Blit(FBO *out, const iRect &src, const iRect &dst, bool color = true, bool depth = true) = 0;
|
||||
/// Transfer color pixels into a CPU based buffer, this buffer is expected to be big enough to hold the required region in RGBA format.
|
||||
virtual void ReadColorPixels(char *out, int x, int y, int w, int h) = 0;
|
||||
|
||||
/// Create FBO.
|
||||
virtual bool Create() = 0;
|
||||
/// Free FBO.
|
||||
virtual void Free() = 0;
|
||||
|
||||
FBO(Renderer &r) : renderer(r)
|
||||
{
|
||||
for (uint n = 0; n < 8; ++n)
|
||||
color_texture[n] = 0;
|
||||
color_texture_count = 0;
|
||||
depth_texture = 0;
|
||||
}
|
||||
virtual ~FBO() {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUFBO__
|
||||
46
include/engine/gpu/gpu_geometry.h
Normal file
46
include/engine/gpu/gpu_geometry.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUGEOMETRY__
|
||||
#define __GPUGEOMETRY__
|
||||
|
||||
|
||||
#include "gpu/gpu_display_list.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace Render { struct Material; }
|
||||
namespace GPU {
|
||||
|
||||
struct Geometry : public Render::Geometry
|
||||
{
|
||||
Renderer &renderer;
|
||||
|
||||
Array <AutoPtr <VBO> > vbo;
|
||||
Array <AutoPtr <DisplayList> > display_list;
|
||||
|
||||
/// Allocate geometry VBO.
|
||||
virtual bool AllocateVBO(uint);
|
||||
/// Get geometry VBO count.
|
||||
virtual uint GetVBOCount() const { return vbo.GetCount(); }
|
||||
/// Get geometry VBO.
|
||||
virtual VBO *GetVBO(uint n) { return (VBO *)&vbo[n]; }
|
||||
|
||||
/// Change a material in the material table.
|
||||
virtual bool SetMaterial(uint index, Render::Material *);
|
||||
|
||||
virtual bool Create(Render::ResourceFactory &, const Core::Geometry &);
|
||||
|
||||
virtual bool ShouldReloadOnDependencyChange(const char *) const;
|
||||
|
||||
Geometry(Renderer &r, const char *name) : Render::Geometry(name), renderer(r) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUGEOMETRY__
|
||||
71
include/engine/gpu/gpu_material.h
Normal file
71
include/engine/gpu/gpu_material.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUMATERIAL__
|
||||
#define __GPUMATERIAL__
|
||||
|
||||
|
||||
#include "gpu/gpu_material_shader.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
struct DrawContext;
|
||||
|
||||
//
|
||||
struct Material : public Render::Material
|
||||
{
|
||||
Renderer &renderer;
|
||||
|
||||
enum SpecularState
|
||||
{
|
||||
SpecularNone = 0,
|
||||
SpecularEnabled,
|
||||
|
||||
SpecularStateCount
|
||||
};
|
||||
|
||||
enum FogState
|
||||
{
|
||||
FogNone = 0,
|
||||
FogLinear,
|
||||
|
||||
FogStateCount
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
SpecularState specular;
|
||||
FogState fog;
|
||||
|
||||
State(FogState _f = FogNone, SpecularState _s = SpecularNone)
|
||||
{
|
||||
fog = _f;
|
||||
specular = _s;
|
||||
}
|
||||
};
|
||||
|
||||
sMaterialShader shader;
|
||||
|
||||
bool LoadTextureTable(Render::ResourceFactory &, const Core::Material &);
|
||||
|
||||
virtual Render::MaterialShader *GetShader() const { return shader; }
|
||||
|
||||
virtual bool Create(Render::ResourceFactory &, const Core::Material &);
|
||||
|
||||
virtual bool ShouldReloadOnDependencyChange(const char *) const;
|
||||
|
||||
virtual Render::Material *Clone() const;
|
||||
|
||||
Material(Renderer &r, const char *name = 0) : Render::Material(name), renderer(r) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUMATERIAL__
|
||||
105
include/engine/gpu/gpu_material_shader.h
Normal file
105
include/engine/gpu/gpu_material_shader.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUMATERIALSHADER__
|
||||
#define __GPUMATERIALSHADER__
|
||||
|
||||
|
||||
#include "gpu/gpu_shader.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
// Static parameters influencing a material shader.
|
||||
struct MaterialShaderStaticParm
|
||||
{
|
||||
bool no_lighting;
|
||||
bool use_alpha_test;
|
||||
bool use_depth_bias;
|
||||
bool use_skinning;
|
||||
|
||||
bool operator == (const MaterialShaderStaticParm &p) const
|
||||
{ return (no_lighting == p.no_lighting) && (use_alpha_test == p.use_alpha_test) && (use_depth_bias == p.use_depth_bias) && (use_skinning == p.use_skinning); }
|
||||
};
|
||||
|
||||
// Shader compiled for a material.
|
||||
class MaterialShader : public Render::MaterialShader
|
||||
{
|
||||
Renderer &renderer;
|
||||
|
||||
String name;
|
||||
|
||||
MaterialShaderStaticParm parm;
|
||||
|
||||
void CompileForwardPointLight(Core::Shader &, bool shadow);
|
||||
void CompileForwardSpotLight(Core::Shader &, bool shadow, bool projection_map);
|
||||
void CompileForwardLinearLight(Core::Shader &, bool shadow);
|
||||
bool CompileShaderSection(const char *, Core::Shader &);
|
||||
|
||||
public:
|
||||
|
||||
enum Variant
|
||||
{
|
||||
Depth, // Shadow map program.
|
||||
|
||||
/*!
|
||||
@name Deferred shading programs.
|
||||
@{
|
||||
*/
|
||||
DS_GBufferMRT4,
|
||||
/*!
|
||||
@}
|
||||
@name Forward shading programs.
|
||||
@{
|
||||
*/
|
||||
FS_Constant,
|
||||
|
||||
FS_PointLight,
|
||||
FS_PointLightShadowMapping,
|
||||
|
||||
FS_LinearLight,
|
||||
FS_LinearLightShadowMapping,
|
||||
|
||||
FS_SpotLight,
|
||||
FS_SpotLightShadowMapping,
|
||||
FS_SpotLightProjection,
|
||||
FS_SpotLightProjectionShadowMapping,
|
||||
|
||||
PP_NormalDepth, // Used by the SSAO post-process.
|
||||
/*!
|
||||
@}
|
||||
@name Common programs.
|
||||
@{
|
||||
*/
|
||||
PP_Velocity,
|
||||
/// @}
|
||||
|
||||
Last
|
||||
};
|
||||
|
||||
const String &GetName() const { return name; }
|
||||
const MaterialShaderStaticParm &GetStaticParm() const { return parm; }
|
||||
|
||||
Array <SharedPtr <Shader> > variants;
|
||||
|
||||
virtual bool SetUserUniformValue(const char *name, const Vector4 &);
|
||||
virtual bool SetUserUniformValue(const char *name, Render::Texture *);
|
||||
|
||||
bool SetupMaterialProgram(Variant, Core::Shader &);
|
||||
bool Create(Render::ResourceFactory &, const Core::Shader &, const MaterialShaderStaticParm &);
|
||||
|
||||
MaterialShader(Renderer &);
|
||||
~MaterialShader();
|
||||
};
|
||||
|
||||
typedef SharedPtr <MaterialShader> sMaterialShader;
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUMATERIALSHADER__
|
||||
61
include/engine/gpu/gpu_perf_tools.h
Normal file
61
include/engine/gpu/gpu_perf_tools.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUPERFTOOLS__
|
||||
#define __GPUPERFTOOLS__
|
||||
|
||||
|
||||
#include "ntypes.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
struct PerformanceTools
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
bool show_wireframe;
|
||||
bool disable_fog;
|
||||
|
||||
PerformanceTools()
|
||||
{
|
||||
show_wireframe = false;
|
||||
disable_fog = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct RendererStatistics
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
uint terrain_page_query_count,
|
||||
terrain_page_query_miss;
|
||||
|
||||
uint prg_change,
|
||||
dls_change,
|
||||
mat_change,
|
||||
item_change;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
terrain_page_query_count = 0;
|
||||
terrain_page_query_miss = 0;
|
||||
|
||||
prg_change = 0;
|
||||
dls_change = 0;
|
||||
mat_change = 0;
|
||||
item_change = 0;
|
||||
}
|
||||
RendererStatistics()
|
||||
{ Reset(); }
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUPERFTOOLS__
|
||||
36
include/engine/gpu/gpu_render_list.h
Normal file
36
include/engine/gpu/gpu_render_list.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPU_RENDER_LIST__
|
||||
#define __GPU_RENDER_LIST__
|
||||
|
||||
|
||||
#include "gpu/gpu_display_list.h"
|
||||
#include "core/renderable.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
struct RenderableList
|
||||
{
|
||||
AutoStack <Render::Primitive *> primitive_list;
|
||||
AutoStack <RenderPrimitive *> display_lists[3];
|
||||
|
||||
// 0 - opaque, 1 - transparent, 2 - framebuffer dependent
|
||||
void Clear(bool free_internals = true)
|
||||
{
|
||||
primitive_list.Clear(free_internals);
|
||||
for (int n = 0; n < 3; ++n)
|
||||
display_lists[n].Clear(free_internals);
|
||||
}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPU_RENDER_LIST__
|
||||
647
include/engine/gpu/gpu_renderer.h
Normal file
647
include/engine/gpu/gpu_renderer.h
Normal file
@ -0,0 +1,647 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPURENDERER__
|
||||
#define __GPURENDERER__
|
||||
|
||||
|
||||
#include "gpu/gpu_shader_object.h"
|
||||
#include "gpu/gpu_fbo.h"
|
||||
#include "gpu/gpu_vbo.h"
|
||||
#include "gpu/gpu_render_list.h"
|
||||
#include "gpu/gpu_draw_context.h"
|
||||
#include "gpu/gpu_config.h"
|
||||
#include "gpu/gpu_shader_compiler.h"
|
||||
#include "gpu/gpu_perf_tools.h"
|
||||
#include "gpu/gpu_terrain.h"
|
||||
#include "gpu/gpu_caps.h"
|
||||
#include "core/render_resource_factory.h"
|
||||
#include "core/renderer.h"
|
||||
#include "core/camera.h"
|
||||
#include "memory/nweak_ptr.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
class PrepareLightJob;
|
||||
|
||||
/*!
|
||||
@short GPU based renderer class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class Renderer : public Render::Renderer
|
||||
{
|
||||
AutoPtr <Render::ResourceFactory> core_resource_factory;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
@name Factories.
|
||||
@{
|
||||
*/
|
||||
virtual FBO *NewFBO() = 0;
|
||||
virtual VBO *NewVBO() = 0;
|
||||
virtual DisplayList *NewDisplayList() = 0;
|
||||
virtual ShaderObject *NewGPUShaderObject() = 0;
|
||||
/*!
|
||||
@}
|
||||
@name Render path.
|
||||
@{
|
||||
*/
|
||||
bool pending_shadow_map_refresh,
|
||||
pending_core_shader_refresh,
|
||||
pending_technique_refresh,
|
||||
pending_fx_refresh;
|
||||
|
||||
RendererConfig gpu_config;
|
||||
PerformanceTools performance_tools;
|
||||
|
||||
/// Process registry message.
|
||||
virtual RegistryRValue ProcessMessage(RegistryMessage message, const Registry *, const void *parm);
|
||||
|
||||
/// Query a caps on the renderer.
|
||||
virtual bool QueryCaps(Caps, Variant &) { return false; }
|
||||
/// Discover and apply the GPU configuration.
|
||||
virtual void DiscoverGPUConfiguration();
|
||||
/// @}
|
||||
|
||||
enum RenderTechnique
|
||||
{
|
||||
TechniqueDefault = 0,
|
||||
TechniqueForward, ///< Forward rendering
|
||||
TechniqueDeferred ///< Deferred rendering for opaque polygons, forward for alpha polygons.
|
||||
};
|
||||
|
||||
RenderTechnique render_technique;
|
||||
|
||||
/// Return the default render technique.
|
||||
RenderTechnique GetDefaultRenderTechnique() const;
|
||||
|
||||
/// Refresh render technique.
|
||||
void RefreshRenderTechnique();
|
||||
/// Free render technique objects.
|
||||
void FreeRenderTechnique();
|
||||
/// Switch to a specific render technique.
|
||||
void SetRenderTechnique(RenderTechnique = TechniqueDefault);
|
||||
|
||||
/// Setup post-process system.
|
||||
void SetPostProcess(uint k = 0);
|
||||
|
||||
/*!
|
||||
@name Statistics.
|
||||
@{
|
||||
*/
|
||||
RendererStatistics gpu_stats;
|
||||
|
||||
/// Draw the renderer profiler output.
|
||||
virtual void DrawProfilerText(Render::RasterFont *font[2], float &x, float &y);
|
||||
/// Reset statistics.
|
||||
virtual void ResetStatistics()
|
||||
{
|
||||
gpu_stats.Reset();
|
||||
stats.Reset();
|
||||
}
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name State functions.
|
||||
@{
|
||||
*/
|
||||
enum GPUFillMode
|
||||
{
|
||||
FillSolid = 0,
|
||||
FillWireframe,
|
||||
FillLast
|
||||
};
|
||||
|
||||
/// Set primitive fill mode.
|
||||
virtual void SetFillMode(GPUFillMode) = 0;
|
||||
|
||||
enum GPUCullFunc
|
||||
{
|
||||
CullFront = 0,
|
||||
CullBack,
|
||||
CullLast
|
||||
};
|
||||
|
||||
/// Set culling function.
|
||||
virtual void SetCullFunc(GPUCullFunc) = 0;
|
||||
/// Enable culling.
|
||||
virtual void EnableCulling(bool) = 0;
|
||||
|
||||
enum GPUDepthFunc
|
||||
{
|
||||
DepthNever = 0,
|
||||
DepthLess,
|
||||
DepthEqual,
|
||||
DepthLessEqual,
|
||||
DepthGreater,
|
||||
DepthNotEqual,
|
||||
DepthGreaterEqual,
|
||||
DepthAlways,
|
||||
DepthFuncLast
|
||||
};
|
||||
|
||||
/// Set depth function.
|
||||
virtual void SetDepthFunc(GPUDepthFunc) = 0;
|
||||
/// Set depth read.
|
||||
virtual void EnableDepthTest(bool) = 0;
|
||||
/// Set depth write.
|
||||
virtual void EnableDepthWrite(bool) = 0;
|
||||
|
||||
enum BlendFunc
|
||||
{
|
||||
BlendZero = 0,
|
||||
BlendOne,
|
||||
BlendSrcAlpha,
|
||||
BlendOneMinusSrcAlpha,
|
||||
BlendDstAlpha,
|
||||
BlendOneMinusDstAlpha,
|
||||
BlendLast
|
||||
};
|
||||
|
||||
/// Set blend function.
|
||||
virtual void SetBlendFunc(BlendFunc src, BlendFunc dst) = 0;
|
||||
/// Enable blend.
|
||||
virtual void EnableBlending(bool) = 0;
|
||||
|
||||
/// Enable alpha to coverage.
|
||||
virtual void EnableAlphaToCoverage(bool) = 0;
|
||||
/// Enable alpha testing.
|
||||
virtual void EnableAlphaTest(bool, float threshold = 0.f) = 0;
|
||||
|
||||
/// Set vertex buffer object.
|
||||
virtual void SetVertexSource(VBO *, size_t stride) = 0;
|
||||
/// Set index buffer object.
|
||||
virtual void SetIndexSource(VBO *) = 0;
|
||||
|
||||
/// Set shader object.
|
||||
virtual bool SetShaderProgram(Shader *, Shader *unset = 0) = 0;
|
||||
|
||||
/// Set display list.
|
||||
virtual void SetDisplayList(DisplayList *);
|
||||
|
||||
protected:
|
||||
|
||||
Matrix4 m_projection,
|
||||
m_view, m_iview,
|
||||
m_world, m_iworld;
|
||||
|
||||
Matrix4 m_previous_iview, // Motion blur specific.
|
||||
m_previous_world;
|
||||
/// @}
|
||||
|
||||
SharedPtr <Shader>
|
||||
single_texture_color_program,
|
||||
single_texture_program,
|
||||
single_color_program,
|
||||
simple_program,
|
||||
|
||||
tone_mapping_program,
|
||||
single_texture_cutoff_program,
|
||||
single_texture_fx_program,
|
||||
shader_program,
|
||||
|
||||
fx_blur_program,
|
||||
noise_program,
|
||||
sharpen_program,
|
||||
hsl_program,
|
||||
chromatic_dispersion_program,
|
||||
|
||||
ssaa_program,
|
||||
ssao_program,
|
||||
ssao_blur_program,
|
||||
|
||||
radial_blur_program,
|
||||
motion_blur_program,
|
||||
|
||||
skybox_program;
|
||||
|
||||
/*!
|
||||
@name Terrain system.
|
||||
@{
|
||||
*/
|
||||
Array <char> terrain_patch_vtx;
|
||||
Array <CachedTerrainPatch> terrain_patch_cache;
|
||||
|
||||
/// Ensure lower entries will get out of cache.
|
||||
void DecayTerrainCache();
|
||||
/// Upload a terrain patch to a cache page.
|
||||
void UploadTerrainPatchToPage(CachedTerrainPatch &page, const Core::Item &item, const Core::Patch &patch, const DrawContext &dc);
|
||||
/// Render a terrain patch.
|
||||
void RenderTerrainPatch(const Core::Patch &, const Core::Item &, const DrawContext &);
|
||||
|
||||
public:
|
||||
|
||||
/// Set default states.
|
||||
void SetDefaultStates();
|
||||
/// Setup core resources.
|
||||
bool SetupCoreResources(bool support_3d = true);
|
||||
|
||||
/// Invalidate the terrain cache.
|
||||
void InvalidateTerrainCache(int u = 0, int v = 0, int w = 0, int h = 0);
|
||||
/// Create the static terrain patch.
|
||||
bool CreateTerrainPatch();
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Core shader.
|
||||
@{
|
||||
*/
|
||||
protected:
|
||||
|
||||
NML::File shader_dict,
|
||||
material_dict;
|
||||
|
||||
/// Marshall core shader source.
|
||||
void MarshallCoreShader(String &source);
|
||||
|
||||
/// Load a shader from a resource file.
|
||||
Shader *SetupCoreShader(const char *name);
|
||||
|
||||
bool LoadCoreShaders(bool support_3d = true);
|
||||
void UnloadCoreShaders();
|
||||
|
||||
public:
|
||||
|
||||
AutoPtr <IShaderCompiler> shader_compiler;
|
||||
|
||||
List <MaterialShader *> material_shaders;
|
||||
|
||||
List <Render::Texture *> textures;
|
||||
List <Render::Shader *> shaders;
|
||||
|
||||
NML::Tag *GetPCFShaderTag() const;
|
||||
NML::Tag *GetPSMShaderTag() const;
|
||||
NML::Tag *GetPSSMShaderTag() const;
|
||||
|
||||
const NML::File &GetShaderDictionary() const
|
||||
{ return shader_dict; }
|
||||
const NML::File &GetMaterialDict() const
|
||||
{ return material_dict; }
|
||||
|
||||
uint fx_scale;
|
||||
FBO *render_fbo;
|
||||
|
||||
bool normal_depth_updated;
|
||||
|
||||
AutoPtr <FBO> buffer_fbo, fx_fbo;
|
||||
Render::sTexture t_compose[2], t_depth; ///< 1:1
|
||||
Render::sTexture t_color_aa, t_depth_aa; ///< 1:1
|
||||
Render::sTexture t_fx[3], t_fx_depth; ///< Downscaled FX render targets.
|
||||
|
||||
AutoPtr <FBO> resolve_fbo; ///< For MSAA support.
|
||||
|
||||
FBO *output_fbo;
|
||||
iRect output_fbo_rect;
|
||||
|
||||
AutoPtr <FBO> shadow_map_fbo;
|
||||
Render::sTexture shadow_map;
|
||||
|
||||
float pcf_radius;
|
||||
float frame_clock;
|
||||
|
||||
Render::sTexture t_noise;
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Post-processes.
|
||||
@{
|
||||
*/
|
||||
Render::Texture *t_final;
|
||||
|
||||
/// Apply directional blur to a texture.
|
||||
void ApplyDirectionalBlur(Render::Texture *t[2], const Vector2 &d, float attn = 0.975f);
|
||||
|
||||
void ApplyBloomFilter(Render::Texture *t, float strength, float threshold, float exponent, float radius, float strength_white_screen);
|
||||
bool ApplyNoiseFilter(Render::Texture *t_in, Render::Texture *t_out, float strength, float monochromatic, float bias);
|
||||
bool ApplySharpenFilter(Render::Texture *t_in, Render::Texture *t_out, float strength);
|
||||
bool ApplyHSL(Render::Texture *t_in, Render::Texture *t_out, float H, float S, float L);
|
||||
bool ApplyChromaticDispersion(Render::Texture *t_in, Render::Texture *t_out, float width);
|
||||
bool ApplySSAAFilter(Render::Texture *t_in, Render::Texture *t_out);
|
||||
bool ApplySSAOFilter(Render::Texture *t_in, Render::Texture *t_out, const Stack <RenderPrimitive *> [2], float strength, float radius, float clip_distance, float blur_radius);
|
||||
bool ApplyRadialBlur(Render::Texture *t_in, Render::Texture *t_out, float strength, float center_x, float center_y);
|
||||
bool ApplyMotionBlur(Render::Texture *t_in, Render::Texture *t_out, const Stack <RenderPrimitive *> [2], float strength, int quality = 1);
|
||||
|
||||
void GetPostProcessNormalDepth(const Stack <RenderPrimitive *> display_lists[2]);
|
||||
|
||||
/// Apply post-processes.
|
||||
Render::Texture *ApplyPostProcessChain(const Stack <RenderPrimitive *> [2]);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Deferred shading.
|
||||
@{
|
||||
*/
|
||||
|
||||
Render::sTexture t_gbuffer[4];
|
||||
|
||||
protected:
|
||||
|
||||
struct ViewConfig
|
||||
{
|
||||
Core::Camera *camera;
|
||||
fRect viewport;
|
||||
|
||||
ViewConfig(Core::Camera *c, const fRect &v) : camera(c), viewport(v) {}
|
||||
};
|
||||
|
||||
fRect viewport;
|
||||
fRect clipping;
|
||||
|
||||
/// Backup the current view configuration.
|
||||
ViewConfig BackupView() const;
|
||||
/// Restore a view configuration.
|
||||
void RestoreView(const ViewConfig &);
|
||||
/// Restore a view configuration viewport.
|
||||
void RestoreViewport(const ViewConfig &);
|
||||
|
||||
/// Allocate shadow map.
|
||||
void CreateShadowMaps();
|
||||
/// Free shadow map.
|
||||
void FreeShadowMaps();
|
||||
|
||||
AutoPtr <Shader> ambient_program,
|
||||
pointlight_program,
|
||||
pointlight_shadow_program,
|
||||
spotlight_program,
|
||||
spotlight_shadow_program,
|
||||
linearlight_program,
|
||||
linearlight_shadow_program;
|
||||
|
||||
AutoPtr <Shader> ds_fog_program;
|
||||
|
||||
/// Render fullscreen light volume.
|
||||
void RenderFullscreenLight(Shader &, Core::Light &);
|
||||
/// Render point light volume.
|
||||
void RenderPointLight(Core::Light &, const DrawContext &);
|
||||
/// Render spot light volume.
|
||||
void RenderSpotLight(Core::Light &, const DrawContext &);
|
||||
/// Render linear light volume.
|
||||
void RenderLinearLight(Core::Light &, const DrawContext &);
|
||||
|
||||
public:
|
||||
|
||||
struct ShadowMapSplit
|
||||
{
|
||||
Core::Camera view;
|
||||
RenderableList list;
|
||||
fRect rect;
|
||||
};
|
||||
|
||||
bool LightPreparePSM(const Core::Light &, bool build_dlist) const;
|
||||
bool LightPreparePSSM(const Core::Light &, bool build_dlist) const;
|
||||
bool LightPrepareSSM(const Core::Light &, bool build_dlist) const;
|
||||
|
||||
/// Prepare shadow map for a light.
|
||||
bool PrepareShadowMap(const Core::Light &, bool build_dlist) const;
|
||||
|
||||
void LightRenderPSM(Core::Light &);
|
||||
void LightRenderSSM(Core::Light &);
|
||||
void LightRenderPSSM(Core::Light &);
|
||||
|
||||
/// Render shadow map for a light.
|
||||
void RenderShadowMap(Core::Light &);
|
||||
/*!
|
||||
@}
|
||||
@name Deferred render pass.
|
||||
@{
|
||||
*/
|
||||
protected:
|
||||
|
||||
/// Render G-buffer map.
|
||||
void RenderGBufferPass(const Stack <RenderPrimitive *> &);
|
||||
/// Render light accumulation map.
|
||||
void RenderDeferredLightPass(const Stack <RenderPrimitive *> &);
|
||||
|
||||
/// Render primitive list using deferred shading.
|
||||
void RenderListDeferred(const Stack <RenderPrimitive *> &);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@}
|
||||
@name Forward render pass.
|
||||
@{
|
||||
*/
|
||||
void SetupForwardContext(const DrawContext::Context &);
|
||||
|
||||
/// Cull display lists against a given light volume.
|
||||
void LightCullDisplayList(const Core::Light &, const Stack <RenderPrimitive *> &in, Stack <RenderPrimitive *> &out);
|
||||
/// Render primitive list using forward rendering.
|
||||
void RenderListForward(Stack <RenderPrimitive *> &, DrawContext::Render);
|
||||
|
||||
void DrawForwardLightContribution(DrawContext::Render, const List <Core::Light *> &, const AutoStack <PrepareLightJob *> &, const Array <Stack <RenderPrimitive *> > &);
|
||||
void DrawForwardBaseConstant(DrawContext::Render, const Stack <RenderPrimitive *> &);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Common render pass.
|
||||
@{
|
||||
*/
|
||||
RenderableList frustum_rlist, shadow_rlist;
|
||||
|
||||
struct DisplayListCache
|
||||
{
|
||||
DrawContext::Context ctx;
|
||||
|
||||
DisplayList *dls;
|
||||
Material *mat;
|
||||
Shader *shd;
|
||||
|
||||
const Core::Item *item;
|
||||
float opacity;
|
||||
|
||||
DisplayListCache() : dls(0), mat(0), shd(0), item(0), opacity(-1.f) {}
|
||||
};
|
||||
|
||||
DisplayListCache dls_cache;
|
||||
|
||||
/// Reset the display list cache.
|
||||
void ResetDisplayListCache();
|
||||
/// Set draw context.
|
||||
bool SetDrawContext(DisplayList &, const Core::Item &, const DrawContext &);
|
||||
/// Draw a display list using the current renderer cache state.
|
||||
void DrawDisplayListCached(DisplayList &, const Core::Item &, const DrawContext &);
|
||||
|
||||
/// Set direct primitive draw state.
|
||||
void DrawSetState(Core::Material::BlendOperator bo, Core::Material::RenderWord f);
|
||||
/// Restore direct primitive draw state.
|
||||
void DrawRestoreState(Core::Material::BlendOperator bo, Core::Material::RenderWord f);
|
||||
|
||||
/// Render skybox.
|
||||
void DrawSkybox(Render::sTexture [2], Render::Shader * = 0);
|
||||
|
||||
public:
|
||||
|
||||
/// Draw primitive list using a specific program.
|
||||
void DrawList(const Stack <RenderPrimitive *> &, const DrawContext &);
|
||||
/// Build display lists.
|
||||
void BuildDisplayLists(const AutoStack <Render::Primitive *> &, AutoStack <RenderPrimitive *> *) const;
|
||||
/// Sort display list per render attributes.
|
||||
void SortDisplayList(AutoStack <RenderPrimitive *> &) const;
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Helper functions.
|
||||
@{
|
||||
*/
|
||||
AutoPtr <VBO> helper_idx_vbo, helper_vtx_vbo;
|
||||
AutoPtr <VBO> skybox_idx_vbo, skybox_vtx_vbo;
|
||||
|
||||
AutoPtr <VBO> direct_idx_vbo, direct_vtx_vbo;
|
||||
|
||||
AutoPtr <VBO> box_idx_vbo; // for deferred light volume drawing
|
||||
|
||||
/// Render a fullscreen quad.
|
||||
void RenderFullscreenQuad(Shader &, float k_x, float k_y, Render::Texture * = 0, Core::Light * = 0);
|
||||
void RenderFullscreenQuad(Shader &, const fRect &nUnused(src_rect), const fRect &nUnused(dst_rect), Render::Texture * = 0, Core::Light * = 0);
|
||||
|
||||
/// Translate a shader from ISL to the target platform language.
|
||||
virtual bool TranslateShader(const Core::Shader &, String &, String &) const = 0;
|
||||
|
||||
/// Set output FBO object (the current frame buffer is blit over this FBO color attachment in EndDrawList).
|
||||
void SetOutputFBO(FBO *fbo = 0, const iRect *rect = 0)
|
||||
{
|
||||
output_fbo = fbo;
|
||||
if (rect)
|
||||
output_fbo_rect = *rect;
|
||||
}
|
||||
|
||||
int GetAnisotropySampleCount(Render::TextureParm::Anisotropy) const;
|
||||
|
||||
/// Set current FBO.
|
||||
virtual void SetCurrentFBO(FBO * = 0) = 0;
|
||||
/// Check the current FBO state.
|
||||
virtual bool CheckCurrentFBO() = 0;
|
||||
|
||||
struct DirectVertexLayout
|
||||
{
|
||||
size_t stride;
|
||||
size_t vtx_offset, color_offset, uv_offset;
|
||||
};
|
||||
|
||||
/// Helper to build a direct vertex layout from distinct input streams.
|
||||
bool BuildDirectVertexLayout(uint idx_count, const ushort *idx, const Vector4 *v, const Color *c, const Vector2 *uv, DirectVertexLayout &, VBO *idx_vbo = 0, VBO *vtx_vbo = 0);
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Performance functions.
|
||||
@{
|
||||
*/
|
||||
/// Set a single shot event.
|
||||
virtual void PerfSetMarker(const char *name, const Color &) {}
|
||||
|
||||
/// Start a performance event.
|
||||
virtual void PerfBeginEvent(const char *name, const Color &) {}
|
||||
/// End a performance event.
|
||||
virtual void PerfEndEvent() {}
|
||||
|
||||
//
|
||||
struct ScopedPerfEvent
|
||||
{
|
||||
Renderer *renderer;
|
||||
|
||||
ScopedPerfEvent(Renderer *_renderer, const char *name, const Color &color) : renderer(_renderer)
|
||||
{ renderer->PerfBeginEvent(name, color); }
|
||||
~ScopedPerfEvent()
|
||||
{ renderer->PerfEndEvent(); }
|
||||
};
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Low-level draw.
|
||||
@{
|
||||
*/
|
||||
/// Set material.
|
||||
void SetMaterial(const Material &, const DrawContext::Context &, bool force_alpha = false);
|
||||
/// Unset material.
|
||||
void UnsetMaterial(const Material &, const DrawContext::Context &);
|
||||
|
||||
/// Draw elements.
|
||||
virtual void DrawElements(Types::PrimitiveType p_type, int index_count, Types::ValueType i_type = Types::ValueLast, const void *indice = 0) = 0;
|
||||
/// @}
|
||||
|
||||
/// Set the view matrix.
|
||||
void SetViewMatrix(const Matrix4 &, const Matrix4 *inverse = 0);
|
||||
/// Set the projection matrix.
|
||||
void SetProjectionMatrix(const Matrix4 &);
|
||||
/// Set the world matrix.
|
||||
void SetWorldMatrix(const Matrix4 &, const Matrix4 *inverse = 0);
|
||||
|
||||
/// Draw a line to the frame buffer.
|
||||
virtual void DrawLine(uint count, const Vector4 *, const Color * = 0, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Render::Shader * = 0);
|
||||
/// Draw a triangle to frame buffer.
|
||||
virtual void DrawTriangle(uint count, const Vector4 *, const ushort * = 0, const Color * = 0, const Vector2 * = 0, const Render::Texture * = 0, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Render::Shader * = 0);
|
||||
/// Draw sprite.
|
||||
virtual void DrawSprite(uint count, const Vector4 *, const Color * = 0, const float *size = 0, const Render::Texture * = 0, float global_size = 1.f, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Render::Shader * = 0);
|
||||
|
||||
/*!
|
||||
@name Render-to-texture and spline rendering.
|
||||
@author Nicolas RACOT
|
||||
@{
|
||||
*/
|
||||
/// Create a render-target texture.
|
||||
Render::Texture *CreateRenderTexture(const char *name, uint width, uint height, Render::Texture::Format format = Render::Texture::FormatRGBA8, Render::Texture::AA aa = Render::Texture::NoAA);
|
||||
/// Clear a texture with a solid color.
|
||||
void ClearTexture(Render::Texture *target, const Color &clear_color = Color(0,0,0,0));
|
||||
/// Copy/blit a source texture to a destination texture.
|
||||
void BlitTextureToTexture(Render::Texture *src, Render::Texture *dst, const fRect *src_rect = 0, const fRect *dst_rect = 0);
|
||||
/// Draw an interpolated spline on a texture with configurable width and color.
|
||||
void DrawSplineToTexture(Render::Texture *target, const Array<Vector2> &control_points, float width_pixels, const Color &color, int samples_per_segment = 16, bool clear_target = false, bool soft_edge = true, const Color *border_color = nullptr, float border_width = 0.0f, float margin = 0.0f);
|
||||
|
||||
private:
|
||||
/// Helper structure for spline tessellation.
|
||||
struct SplineRibbon
|
||||
{
|
||||
Array<Vector4> positions;
|
||||
Array<ushort> indices;
|
||||
Array<Color> colors;
|
||||
Array<Vector2> uvs; // for soft edge (distance from centerline)
|
||||
};
|
||||
|
||||
/// Catmull-Rom spline interpolation.
|
||||
Vector2 CatmullRomInterpolate(const Vector2 &p0, const Vector2 &p1, const Vector2 &p2, const Vector2 &p3, float t) const;
|
||||
/// Tessellate a spline into ribbon geometry.
|
||||
void TessellateSplineRibbon(const Array<Vector2> &control_points, float width_normalized, const Color &color, int samples_per_segment, bool soft_edge, SplineRibbon &out_ribbon);
|
||||
|
||||
public:
|
||||
/// @}
|
||||
|
||||
/// Initialize platform.
|
||||
virtual bool InitializePlatform() = 0;
|
||||
/// Open platform video system.
|
||||
virtual bool OpenPlatformVideo(uint w, uint h, char d, Render::VideoMode m, const void *sys_handle = 0) = 0;
|
||||
/// Close platform video system.
|
||||
virtual void ClosePlatformVideo() = 0;
|
||||
|
||||
/// Render the display list.
|
||||
void RenderList();
|
||||
|
||||
/// Output string to screen.
|
||||
virtual void Write(const Render::RasterFont &, const char *, float &x, float &y, const WriterConfig &, float s = 1, const Color *c = 0, WriterAlignment a = AlignLeft, bool mirrored = false);
|
||||
|
||||
/// Open video.
|
||||
virtual bool Open(uint w, uint h, char d = 32, Render::VideoMode m = Render::VideoWindowed, const void *sys_handle = 0);
|
||||
/// Free all renderer resources.
|
||||
virtual void Free();
|
||||
/// Close video.
|
||||
virtual void Close();
|
||||
/// Explicitly resize video output.
|
||||
virtual bool ResizeVideo(uint w, uint h);
|
||||
|
||||
/// Begin a drawing operation.
|
||||
bool BeginDrawList();
|
||||
/// End a drawing operation.
|
||||
void EndDrawList();
|
||||
|
||||
Renderer();
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPURENDERER__
|
||||
165
include/engine/gpu/gpu_shader.h
Normal file
165
include/engine/gpu/gpu_shader.h
Normal file
@ -0,0 +1,165 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUSHADER__
|
||||
#define __GPUSHADER__
|
||||
|
||||
|
||||
#include "gpu/gpu_types.h"
|
||||
#include "gpu/gpu_shader_object.h"
|
||||
#include "core/render_data.h"
|
||||
#include "core/shader_tree_compiler.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
namespace Core {
|
||||
class Item;
|
||||
class Camera;
|
||||
class Light;
|
||||
struct Skin;
|
||||
}
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
struct DisplayList;
|
||||
struct Material;
|
||||
struct DrawContext;
|
||||
|
||||
//
|
||||
struct ShaderInputLocation
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
virtual ~ShaderInputLocation() {}
|
||||
};
|
||||
|
||||
//
|
||||
struct ShaderInput
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
String name;
|
||||
|
||||
Core::ShaderInput::Type type;
|
||||
Core::ShaderInput::Semantic semantic;
|
||||
Core::ShaderInput::DataType data_type;
|
||||
|
||||
Render::sTexture parm_t; ///< 4B texture
|
||||
Vector4 parm_v; ///< 16B vector
|
||||
|
||||
int index;
|
||||
|
||||
AutoPtr <ShaderInputLocation> location;
|
||||
|
||||
void SetValue(float v) { parm_v.Set(v); }
|
||||
void SetValue(float x, float y) { parm_v.Set(x, y); }
|
||||
void SetValue(float x, float y, float z) { parm_v.Set(x, y, z); }
|
||||
void SetValue(const Vector2 &v) { parm_v.Set(v.x, v.y); }
|
||||
void SetValue(const Vector4 &v) { parm_v = v; }
|
||||
void SetValue(Render::Texture *t) { parm_t = t; }
|
||||
|
||||
void Set(Core::ShaderInput *input)
|
||||
{
|
||||
index = -1;
|
||||
|
||||
name = input->name;
|
||||
parm_v = input->parm_v;
|
||||
data_type = input->data_type;
|
||||
|
||||
semantic = input->semantic;
|
||||
type = input->type;
|
||||
}
|
||||
|
||||
ShaderInput()
|
||||
{
|
||||
index = -1;
|
||||
data_type = Core::ShaderInput::NoData;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short GPU shader.
|
||||
*/
|
||||
struct Shader : public Render::Shader
|
||||
{
|
||||
Renderer &renderer;
|
||||
|
||||
/// Get the input list index for a given semantic.
|
||||
static uint GetSemanticInputList(Core::ShaderInput::Semantic);
|
||||
|
||||
AutoPtr <ShaderObject> vertex, pixel;
|
||||
Array <ShaderInput> input_list[Core::ShaderInput::CategoryLast]; ///< Attributes and uniforms list are split per category.
|
||||
|
||||
/// Get a program parameter from its semantic.
|
||||
ShaderInput *GetInput(Core::ShaderInput::Semantic) const;
|
||||
/// Get a program parameter from its name.
|
||||
ShaderInput *GetInput(const char *) const;
|
||||
|
||||
/// Set vertex stream inputs.
|
||||
void SetVertexStreamInputs(DisplayList &);
|
||||
/// Set skin inputs.
|
||||
void SetSkinInputs(DisplayList &, Core::Skin &);
|
||||
/// Set program inputs.
|
||||
void SetConstantInputs();
|
||||
/// Set texture inputs.
|
||||
void SetTextureInputs();
|
||||
/// Set renderer inputs.
|
||||
void SetRendererInputs(Renderer &, Material * = 0);
|
||||
/// Set transformation inputs.
|
||||
void SetTransformInputs(const Matrix4 &v_pm, const Matrix4 &v_m, const Matrix4 &v_im, const Matrix4 *i_m, const Matrix4 *i_im, uint count = 1);
|
||||
/// Set previous transformation inputs.
|
||||
void SetPreviousTransformInputs(const Matrix4 &v_pm, const Matrix4 &v_im, const Matrix4 *i_m, uint count = 1);
|
||||
/// Set material opacity inputs.
|
||||
void SetMaterialOpacityInputs(Material &, float opacity);
|
||||
/// Set material inputs.
|
||||
void SetMaterialInputs(Material &);
|
||||
/// Set light inputs.
|
||||
void SetLightInputs(Renderer &, Core::Camera &, Core::Light &);
|
||||
|
||||
/// Commit inputs.
|
||||
virtual void CommitInputs() = 0;
|
||||
|
||||
/// New GPU shader location.
|
||||
virtual ShaderInputLocation *NewGPUShaderLocation() = 0;
|
||||
/// Retrieve the location of any program parameter from its declaration name.
|
||||
virtual bool GetLocation(const char *name, ShaderInputLocation &, Core::ShaderInput::Type = Core::ShaderInput::Uniform) = 0;
|
||||
|
||||
/*!
|
||||
@name Uniform accessors.
|
||||
@{
|
||||
*/
|
||||
virtual void Set(const ShaderInputLocation &, const Render::Texture &, int unit) = 0;
|
||||
virtual void Set(const ShaderInputLocation &, const Matrix3 *, int n = 1) = 0;
|
||||
virtual void Set(const ShaderInputLocation &, const Matrix4 *, int n = 1) = 0;
|
||||
virtual void Set(const ShaderInputLocation &, const float *, int n = 1) = 0;
|
||||
virtual void Set(const ShaderInputLocation &, const int *, int n = 1) = 0;
|
||||
|
||||
void Set(const ShaderInputLocation &l, int v) { Set(l, &v); }
|
||||
void Set(const ShaderInputLocation &l, float v) { Set(l, &v); }
|
||||
void Set(const ShaderInputLocation &l, const Matrix3 &m) { Set(l, &m); }
|
||||
void Set(const ShaderInputLocation &l, const Matrix4 &m) { Set(l, &m); }
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
@name Attribute accessors.
|
||||
@{
|
||||
*/
|
||||
virtual void Set(const ShaderInputLocation &, int elem_count, Types::ValueType, bool normalized, size_t stride, const void *offset) = 0;
|
||||
/// @}
|
||||
|
||||
/// Create program.
|
||||
virtual bool Create(Render::ResourceFactory &, const Core::Shader &);
|
||||
|
||||
/// Free program.
|
||||
virtual void Free() = 0;
|
||||
|
||||
Shader(Renderer &r, const char *name) : Render::Shader(name), renderer(r) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUSHADER__
|
||||
47
include/engine/gpu/gpu_shader_compiler.h
Normal file
47
include/engine/gpu/gpu_shader_compiler.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
nEngine - GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPU_SHADER_COMPILER__
|
||||
#define __GPU_SHADER_COMPILER__
|
||||
|
||||
|
||||
#include "gpu/gpu_shader_object.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class String;
|
||||
|
||||
namespace Core { struct Shader; }
|
||||
namespace GPU {
|
||||
struct Shader;
|
||||
class Renderer;
|
||||
|
||||
/*!
|
||||
@short GPU shader compiler interface.
|
||||
@author Emmanuel Julien (ejulien@owloh.com)
|
||||
*/
|
||||
class IShaderCompiler
|
||||
{
|
||||
protected:
|
||||
|
||||
Renderer &renderer;
|
||||
|
||||
virtual bool Link(const Core::Shader &, Shader &) = 0;
|
||||
virtual bool CompileObject(const char *source, ShaderObject &, ShaderObject::Type, const char *source_name, String *error_log) = 0;
|
||||
|
||||
public:
|
||||
|
||||
virtual bool Compile(const Core::Shader &, Shader &, const char *binary_cache_id = 0);
|
||||
|
||||
IShaderCompiler(Renderer &r) : renderer(r) {}
|
||||
virtual ~IShaderCompiler() {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPU_SHADER_COMPILER__
|
||||
39
include/engine/gpu/gpu_shader_object.h
Normal file
39
include/engine/gpu/gpu_shader_object.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUSHADEROBJECT__
|
||||
#define __GPUSHADEROBJECT__
|
||||
|
||||
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
|
||||
//
|
||||
struct ShaderObject
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
enum Type
|
||||
{
|
||||
Vertex = 0,
|
||||
Pixel,
|
||||
|
||||
TypeLast
|
||||
};
|
||||
|
||||
virtual void Free() = 0;
|
||||
|
||||
virtual ~ShaderObject() {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUSHADEROBJECT__
|
||||
40
include/engine/gpu/gpu_terrain.h
Normal file
40
include/engine/gpu/gpu_terrain.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUTERRAIN__
|
||||
#define __GPUTERRAIN__
|
||||
|
||||
|
||||
#include "gpu/gpu_display_list.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace Core { class Terrain; }
|
||||
namespace GPU {
|
||||
struct DisplayList;
|
||||
|
||||
//
|
||||
struct CachedTerrainPatch
|
||||
{
|
||||
NPLACEMENT_NEW(RendererTerrain)
|
||||
|
||||
Core::Terrain *terrain;
|
||||
|
||||
int u, v, w, h;
|
||||
int decimation;
|
||||
|
||||
uint score;
|
||||
|
||||
AutoPtr <DisplayList> patch;
|
||||
|
||||
CachedTerrainPatch() : terrain(0), u(0), v(0), w(-1), h(-1), decimation(0), score(0) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUTERRAIN__
|
||||
29
include/engine/gpu/gpu_texture.h
Normal file
29
include/engine/gpu/gpu_texture.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NGPUTEXTURE__
|
||||
#define __NGPUTEXTURE__
|
||||
|
||||
|
||||
#include "core/render_data.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
|
||||
/// GPU Texture
|
||||
struct Texture : public Render::Texture
|
||||
{
|
||||
Renderer &renderer;
|
||||
Texture(Renderer &r, const char *name = 0) : Render::Texture(name), renderer(r) {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NGPUTEXTURE__
|
||||
52
include/engine/gpu/gpu_triangle_batch.h
Normal file
52
include/engine/gpu/gpu_triangle_batch.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __GPUTRIANGLEBATCH__
|
||||
#define __GPUTRIANGLEBATCH__
|
||||
|
||||
|
||||
#include "core/material.h"
|
||||
#include "core/render_data.h"
|
||||
#include "math/vector.h"
|
||||
#include "color/color.h"
|
||||
#include "container/narray.h"
|
||||
#include "ntypes.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
|
||||
class TriangleBatch
|
||||
{
|
||||
Renderer &renderer;
|
||||
|
||||
uint batch_max_triangle_count;
|
||||
uint batch_triangle_count, batch_attrib_offset;
|
||||
|
||||
Array <ushort> batch_idx;
|
||||
Array <Vector4> batch_vtx;
|
||||
Array <Color> batch_col;
|
||||
Array <Vector2> batch_uv;
|
||||
|
||||
const Render::Texture *batch_t;
|
||||
|
||||
Core::Material::BlendOperator batch_blend_op;
|
||||
Core::Material::RenderWord batch_render_word;
|
||||
|
||||
public:
|
||||
|
||||
void DrawTriangle(uint triangle_count, uint attrib_count, const Vector4 *, const ushort *, const Color *, const Vector2 *uv, const Render::Texture *, Core::Material::BlendOperator, Core::Material::RenderWord);
|
||||
void Flush();
|
||||
|
||||
TriangleBatch(Renderer &, uint batch_max_tri = 1024);
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUTRIANGLEBATCH__
|
||||
57
include/engine/gpu/gpu_types.h
Normal file
57
include/engine/gpu/gpu_types.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUTYPES__
|
||||
#define __GPUTYPES__
|
||||
|
||||
|
||||
#if __PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__
|
||||
//#define EGL_HALF_FLOAT_SUPPORT
|
||||
#endif
|
||||
|
||||
#ifdef EGL_HALF_FLOAT_SUPPORT
|
||||
typedef unsigned short hfloat;
|
||||
#define EGL_HFLOAT GL_HALF_FLOAT_OES
|
||||
#else
|
||||
typedef float hfloat;
|
||||
#define EGL_HFLOAT GL_FLOAT
|
||||
#endif
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
namespace Types {
|
||||
|
||||
enum ValueType
|
||||
{
|
||||
ValueByte,
|
||||
ValueUByte,
|
||||
ValueShort,
|
||||
ValueUShort,
|
||||
ValueFloat,
|
||||
ValueHalfFloat,
|
||||
|
||||
ValueLast
|
||||
};
|
||||
|
||||
enum PrimitiveType
|
||||
{
|
||||
PrimitiveLine,
|
||||
PrimitiveTriangle,
|
||||
|
||||
PrimitiveLast
|
||||
};
|
||||
|
||||
/// Convert float to half-float.
|
||||
hfloat FloatToHFloat(float f);
|
||||
/// Convert float to half-float.
|
||||
float HFloatToFloat(hfloat hf);
|
||||
|
||||
} // Types
|
||||
} // Types
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUTYPES__
|
||||
78
include/engine/gpu/gpu_vbo.h
Normal file
78
include/engine/gpu/gpu_vbo.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __GPUVBO__
|
||||
#define __GPUVBO__
|
||||
|
||||
|
||||
#include "memory/memory.h"
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
namespace GPU {
|
||||
class Renderer;
|
||||
|
||||
/*!
|
||||
@short GPU data buffer object.
|
||||
*/
|
||||
struct VBO
|
||||
{
|
||||
NPLACEMENT_NEW(Renderer)
|
||||
|
||||
enum Usage
|
||||
{
|
||||
Static = 0,
|
||||
Dynamic
|
||||
};
|
||||
enum Type
|
||||
{
|
||||
Index = 0,
|
||||
Vertex
|
||||
};
|
||||
|
||||
Renderer &renderer;
|
||||
|
||||
/// Get VBO size.
|
||||
virtual size_t GetSize() const = 0;
|
||||
|
||||
/// Map VBO to main memory.
|
||||
virtual void *Map() = 0;
|
||||
/// Unmap VBO.
|
||||
virtual void Unmap() = 0;
|
||||
|
||||
/// Update VBO content.
|
||||
virtual bool Update(const void *, size_t start = 0, size_t size = 0) = 0;
|
||||
|
||||
/// Create VBO.
|
||||
virtual bool Create(size_t size, Type = Vertex, Usage = Static) = 0;
|
||||
/// Create VBO, map and set data.
|
||||
virtual bool Create(const void *data, size_t size, Type type = Vertex, Usage usage = Static)
|
||||
{
|
||||
if (!Create(size, type, usage))
|
||||
return false;
|
||||
|
||||
void *p = Map();
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
Memory::Copy(p, data, size);
|
||||
Unmap();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Free VBO.
|
||||
virtual void Free() = 0;
|
||||
|
||||
VBO(Renderer &r) : renderer(r) {}
|
||||
virtual ~VBO() {}
|
||||
};
|
||||
|
||||
} // GPU
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __GPUVBO__
|
||||
Reference in New Issue
Block a user