first commit

This commit is contained in:
2026-06-22 11:49:35 +02:00
commit d805f2ba86
619 changed files with 126873 additions and 0 deletions

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__

View 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__