out vec3 world_look_dir = normalize(world_vertex.xyz-eye_pos);
out float fog_coord = eye_vertex.z;
-
- if(use_clipping)
- {
- for(int i=0; i<max_clip_planes; ++i)
- gl_ClipDistance[i] = dot(world_vertex, clip_planes[i].equation);
- }
}
virtual void custom_transform()
vec3 attenuation;
};
-struct ClipPlane
-{
- vec4 equation;
-};
-
uniform mat4 world_obj_matrix;
uniform mat3 world_obj_normal_matrix;
uniform CameraTransform
float fog_density;
};
-layout(constant_id=auto) const bool use_clipping = false;
-layout(constant_id=auto) const int max_clip_planes = 8;
-uniform Clipping
-{
- ClipPlane clip_planes[max_clip_planes];
-};
-
#pragma MSP stage(vertex)
layout(location=0) in vec4 vertex;
layout(location=1) in vec4 color;
vector<int> OpenGLPipelineState::bound_tex_targets;
vector<char> OpenGLPipelineState::bound_uniform_blocks;
unsigned OpenGLPipelineState::restart_index = 0;
+unsigned OpenGLPipelineState::n_clip_distances = 0;
OpenGLPipelineState::OpenGLPipelineState()
{
}
if(mask&PipelineState::SHPROG)
+ {
glUseProgram(self->shprog ? self->shprog->id : 0);
+ unsigned ncd = (self->shprog ? self->shprog->get_n_clip_distances() : 0);
+ if(ncd!=n_clip_distances)
+ {
+ for(unsigned i=0; (i<ncd || i<n_clip_distances); ++i)
+ {
+ if(i<ncd)
+ glEnable(GL_CLIP_PLANE0+i);
+ else
+ glDisable(GL_CLIP_PLANE0+i);
+ }
+ n_clip_distances = ncd;
+ }
+ }
+
if(mask&PipelineState::VERTEX_SETUP)
{
const VertexSetup *vertex_setup = self->vertex_setup;
glDisable(GL_CULL_FACE);
}
- if(mask&PipelineState::CLIP_PLANES)
- {
- unsigned max_clip_planes = DeviceInfo::get_global().limits.max_clip_planes;
- for(unsigned i=0; i<max_clip_planes; ++i)
- {
- if((self->enabled_clip_planes>>i)&1)
- glEnable(GL_CLIP_PLANE0+i);
- else
- glDisable(GL_CLIP_PLANE0+i);
- }
- }
-
if(mask&PipelineState::TEXTURES)
{
for(const PipelineState::BoundTexture &t: self->textures)
glUseProgram(0);
glBindVertexArray(0);
- unsigned max_clip_planes = DeviceInfo::get_global().limits.max_clip_planes;
- unsigned enabled_clip_planes = static_cast<const PipelineState *>(last_applied)->enabled_clip_planes;
- for(unsigned i=0; i<max_clip_planes; ++i)
- if((enabled_clip_planes>>i)&1)
- glDisable(GL_CLIP_PLANE0+i);
+ for(unsigned i=0; i<n_clip_distances; ++i)
+ glDisable(GL_CLIP_PLANE0+i);
+ n_clip_distances = 0;
for(unsigned i=0; i<bound_tex_targets.size(); ++i)
if(bound_tex_targets[i])
static std::vector<int> bound_tex_targets;
static std::vector<char> bound_uniform_blocks;
static unsigned restart_index;
+ static unsigned n_clip_distances;
OpenGLPipelineState();
~OpenGLPipelineState();
transient.textures = compiler.get_texture_bindings();
transient.blocks = compiler.get_uniform_block_bindings();
+
+ ReflectData &rd = static_cast<Program *>(this)->reflect_data;
+ rd.n_clip_distances = compiler.get_n_clip_distances();
}
void OpenGLProgram::compile_glsl_stage(const GlslModule &mod, unsigned stage_id)
+++ /dev/null
-#include <msp/core/algorithm.h>
-#include "clipping.h"
-#include "clipplane.h"
-#include "deviceinfo.h"
-#include "error.h"
-
-using namespace std;
-
-namespace Msp {
-namespace GL {
-
-void Clipping::attach(const ClipPlane &p)
-{
- if(find_member(planes, &p, &AttachedPlane::plane)!=planes.end())
- return;
- if(planes.size()>=DeviceInfo::get_global().limits.max_clip_planes)
- throw invalid_operation("Clipping::attach");
-
- planes.push_back(&p);
-}
-
-void Clipping::detach(const ClipPlane &p)
-{
- auto i = find_member(planes, &p, &AttachedPlane::plane);
- if(i!=planes.end())
- planes.erase(i);
-}
-
-const ProgramData &Clipping::get_shader_data() const
-{
- for(unsigned i=0; i<planes.size(); ++i)
- if(planes[i].plane->get_generation()!=planes[i].generation)
- {
- planes[i].plane->update_shader_data(shdata, i);
- planes[i].generation = planes[i].plane->get_generation();
- }
-
- return shdata;
-}
-
-} // namespace GL
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_GL_CLIPPING_H_
-#define MSP_GL_CLIPPING_H_
-
-#include <vector>
-#include "programdata.h"
-
-namespace Msp {
-namespace GL {
-
-class ClipPlane;
-
-class Clipping
-{
-private:
- struct AttachedPlane
- {
- const ClipPlane *plane;
- mutable unsigned generation;
-
- AttachedPlane(const ClipPlane *p): plane(p), generation(0) { }
- };
-
- std::vector<AttachedPlane> planes;
- mutable ProgramData shdata;
-
-public:
- void attach(const ClipPlane &);
- void detach(const ClipPlane &);
-
- unsigned get_n_planes() const { return planes.size(); }
-
- const ProgramData &get_shader_data() const;
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
+++ /dev/null
-#include <msp/strings/format.h>
-#include "clipplane.h"
-#include "programdata.h"
-
-namespace Msp {
-namespace GL {
-
-ClipPlane::ClipPlane(const Vector4 &e):
- eq(e)
-{ }
-
-ClipPlane::ClipPlane(const Vector3 &p, const Vector3 &d):
- eq(compose(d, -dot(p, d)))
-{ }
-
-void ClipPlane::set_equation(const Vector4 &e)
-{
- eq = e;
- ++generation;
-}
-
-void ClipPlane::set_plane(const Vector3 &p, const Vector3 &d)
-{
- Vector3 nd = normalize(d);
- set_equation(compose(nd, -dot(p, nd)));
-}
-
-void ClipPlane::update_shader_data(ProgramData &shdata, unsigned i) const
-{
- shdata.uniform(format("clip_planes[%d].equation", i), eq);
-}
-
-} // namespace GL
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_GL_CLIPPLANE_H_
-#define MSP_GL_CLIPPLANE_H_
-
-#include "vector.h"
-
-namespace Msp {
-namespace GL {
-
-class ProgramData;
-
-class ClipPlane
-{
-private:
- Vector4 eq = { 0.0f, 0.0f, 0.0f, 1.0f };
- unsigned generation = 0;
-
-public:
- ClipPlane() = default;
- ClipPlane(const Vector4 &);
- ClipPlane(const Vector3 &, const Vector3 &);
-
- void set_equation(const Vector4 &);
- void set_plane(const Vector3 &, const Vector3 &);
- void update_shader_data(ProgramData &, unsigned) const;
-
- unsigned get_generation() const { return generation; }
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
set(face_cull, c, FACE_CULL);
}
-void PipelineState::set_enabled_clip_planes(unsigned p)
-{
- set(enabled_clip_planes, p, CLIP_PLANES);
-}
-
void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
{
if((tex!=0)!=(samp!=0))
SHPROG = 1,
VERTEX_SETUP = 2,
FACE_CULL = 4,
- CLIP_PLANES = 8,
TEXTURES = 16,
UNIFORMS = 32,
DEPTH_TEST = 64,
const VertexSetup *vertex_setup = 0;
FaceWinding front_face = COUNTERCLOCKWISE;
CullMode face_cull = NO_CULL;
- unsigned enabled_clip_planes = 0;
std::vector<BoundTexture> textures;
std::vector<BoundUniformBlock> uniform_blocks;
const DepthTest *depth_test = 0;
void set_vertex_setup(const VertexSetup *);
void set_front_face(FaceWinding);
void set_face_cull(CullMode);
- void set_enabled_clip_planes(unsigned);
void set_texture(unsigned, const Texture *, const Sampler *);
void set_uniform_block(int, const UniformBlock *);
void set_depth_test(const DepthTest *);
}
}
+void Program::collect_builtins(const SpirVModule &mod)
+{
+ for(const SpirVModule::Variable &v: mod.get_variables())
+ if(v.storage==SpirVModule::OUTPUT && v.struct_type)
+ collect_builtins(*v.struct_type);
+}
+
+void Program::collect_builtins(const SpirVModule::Structure &strct)
+{
+ for(const SpirVModule::StructMember &m: strct.members)
+ if(m.builtin==SpirVModule::CLIP_DISTANCE)
+ reflect_data.n_clip_distances = m.array_size;
+}
+
const ReflectData::UniformBlockInfo &Program::get_uniform_block_info(const string &name) const
{
auto i = find_member(reflect_data.uniform_blocks, name, &ReflectData::UniformBlockInfo::name);
void collect_uniforms(const SpirVModule &, const std::map<unsigned, int> &);
void collect_block_uniforms(const SpirVModule::Structure &, const std::string &, unsigned, const std::map<unsigned, int> &, std::vector<std::string> &);
void collect_attributes(const SpirVModule &);
+ void collect_builtins(const SpirVModule &);
+ void collect_builtins(const SpirVModule::Structure &);
public:
ReflectData::LayoutHash get_uniform_layout_hash() const { return reflect_data.layout_hash; }
const std::vector<ReflectData::AttributeInfo> &get_attributes() const { return reflect_data.attributes; }
const ReflectData::AttributeInfo &get_attribute_info(const std::string &) const;
int get_attribute_location(const std::string &) const;
+ unsigned get_n_clip_distances() const { return reflect_data.n_clip_distances; }
using ProgramBackend::set_debug_name;
};
std::vector<UniformInfo> uniforms;
LayoutHash layout_hash;
std::vector<AttributeInfo> attributes;
+ unsigned n_clip_distances = 0;
void update_layout_hash();
};
return module->shared.uniform_block_bindings;
}
+unsigned Compiler::get_n_clip_distances() const
+{
+ if(!compiled)
+ throw invalid_operation("Compiler::get_n_clip_distances");
+ auto i = find_member(module->stages, Stage::VERTEX, &Stage::type);
+ return (i!=module->stages.end() ? i->n_clip_distances : 0);
+}
+
const SourceMap &Compiler::get_source_map() const
{
return module->source_map;
source). */
const std::map<std::string, unsigned> &get_uniform_block_bindings() const;
+ unsigned get_n_clip_distances() const;
+
/** Returns the mapping of source indices to filenames. Can be used to
translate error messages. */
const SourceMap &get_source_map() const;
}
}
+ if(var.name=="gl_ClipDistance")
+ if(const Literal *literal_size = dynamic_cast<const Literal *>(var.array_size.get()))
+ stage->n_clip_distances = literal_size->value.value<int>();
+
TraversingVisitor::visit(var);
}
std::map<std::string, unsigned> locations;
std::map<std::string, unsigned> texture_bindings;
std::map<std::string, unsigned> uniform_block_bindings;
+ unsigned n_clip_distances = 0;
Features required_features;
std::vector<Diagnostic> diagnostics;
#include "batch.h"
#include "buffer.h"
#include "camera.h"
-#include "clipping.h"
#include "error.h"
#include "framebuffer.h"
#include "lighting.h"
add_shader_data(l->get_shader_data());
}
-void Renderer::set_clipping(const Clipping *c)
-{
- state->clipping = c;
- if(c)
- add_shader_data(c->get_shader_data());
-}
-
void Renderer::set_shader_program(const Program *p, const ProgramData *d)
{
state->shprog = p;
pipeline_state.set_front_face(state->front_face);
pipeline_state.set_face_cull(state->face_cull);
- pipeline_state.set_enabled_clip_planes(state->clipping ? (1<<state->clipping->get_n_planes())-1 : 0);
if(state->texture_count<texture_stack.size())
flush_textures();
class Buffer;
class Camera;
union ClearValue;
-class Clipping;
class Material;
class Mesh;
class Lighting;
const Rect *viewport = 0;
const Rect *scissor = 0;
unsigned texture_count = 0;
- const Clipping *clipping = 0;
const Program *shprog = 0;
unsigned shdata_count = 0;
const VertexSetup *vertex_setup = 0;
DEPRECATED void set_material(const Material *);
DEPRECATED void set_lighting(const Lighting *);
- void set_clipping(const Clipping *);
/** Sets the shader program to use. An initial set of data can be set as
well, with the same semantics as add_shader_data. */
if (const Lighting *lighting = s.get_lighting())
renderer.add_shader_data(lighting->get_shader_data());
- renderer.set_clipping(s.get_clipping());
if(const Renderable *renderable = s.get_renderable())
renderer.render(*renderable, s.get_tag());
Sequence::Step::Step(Tag t, Renderable *r):
tag(t),
lighting(0),
- clipping(0),
renderable(r)
{ }
blend = b;
}
-void Sequence::Step::set_clipping(const Clipping *c)
-{
- clipping = c;
-}
-
} // namespace GL
} // namespace Msp
namespace Msp {
namespace GL {
-class Clipping;
class Lighting;
class PostProcessor;
class RenderTarget;
Renderable for a View or effects such as ShadowMap or EnvironmentMap.
A Sequence consists of a number of steps. Each step is defined with a
-Renderable and a tag to render it with and may also have Lighting, Clipping,
-DepthTest and Blend states. Scenes can be used to further organize Renderables
-within a step.
+Renderable and a tag to render it with and may also have Lighting, DepthTest
+and Blend states. Scenes can be used to further organize Renderables within a
+step.
PostProcessors can be applied after all of the steps in the Sequence have been
processed. Framebuffer objects are automatically used to pass render results
DepthTest depth_test;
StencilTest stencil_test;
Blend blend;
- const Clipping *clipping;
Renderable *renderable;
public:
void set_depth_test(const DepthTest &);
void set_stencil_test(const StencilTest &);
void set_blend(const Blend &);
- void set_clipping(const Clipping *);
const Lighting *get_lighting() const { return lighting; }
const DepthTest &get_depth_test() const { return depth_test; }
const StencilTest &get_stencil_test() const { return stencil_test; }
const Blend &get_blend() const { return blend; }
- const Clipping *get_clipping() const { return clipping; }
Renderable *get_renderable() const { return renderable; }
};