mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-17 18:24:00 +02:00
and make it compile on mac... remove the field map from state just because it's unecessary
This commit is contained in:
parent
ee4b9a483b
commit
1a18719031
5 changed files with 724 additions and 562 deletions
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
template <class T> class Command1 : public Command {
|
||||
public:
|
||||
typedef void (GLBackend::*GLFunction)(typename T);
|
||||
typedef void (GLBackend::*GLFunction)(T);
|
||||
void run(GLBackend* backend) { (backend->*(_func))(_param); }
|
||||
Command1(GLFunction func, T param) : _func(func), _param(param) {};
|
||||
GLFunction _func;
|
||||
|
@ -94,7 +94,7 @@ public:
|
|||
};
|
||||
template <class T, class U> class Command2 : public Command {
|
||||
public:
|
||||
typedef void (GLBackend::*GLFunction)(typename T, typename U);
|
||||
typedef void (GLBackend::*GLFunction)(T, U);
|
||||
void run(GLBackend* backend) { (backend->*(_func))(_param0, _param1); }
|
||||
Command2(GLFunction func, T param0, U param1) : _func(func), _param0(param0), _param1(param1) {};
|
||||
GLFunction _func;
|
||||
|
@ -104,7 +104,7 @@ public:
|
|||
|
||||
template <class T, class U, class V> class Command3 : public Command {
|
||||
public:
|
||||
typedef void (GLBackend::*GLFunction)(typename T, typename U, typename V);
|
||||
typedef void (GLBackend::*GLFunction)(T, U, V);
|
||||
void run(GLBackend* backend) { (backend->*(_func))(_param0, _param1, _param2); }
|
||||
Command3(GLFunction func, T param0, U param1, V param2) : _func(func), _param0(param0), _param1(param1), _param2(param2) {};
|
||||
GLFunction _func;
|
||||
|
@ -171,18 +171,18 @@ public:
|
|||
protected:
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(Batch& batch, uint32 paramOffset);
|
||||
void do_draw(Batch& batch, uint32 paramOffset);
|
||||
void do_drawIndexed(Batch& batch, uint32 paramOffset);
|
||||
void do_drawInstanced(Batch& batch, uint32 paramOffset);
|
||||
void do_drawInstanced(Batch& batch, uint32 paramOffset);
|
||||
void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset);
|
||||
|
||||
// Input Stage
|
||||
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
||||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setInputFormat(Batch& batch, uint32 paramOffset);
|
||||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setIndexBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void updateInput();
|
||||
struct InputStageState {
|
||||
struct InputStageState {
|
||||
bool _invalidFormat;
|
||||
Stream::FormatPointer _format;
|
||||
|
||||
|
@ -215,18 +215,18 @@ protected:
|
|||
} _input;
|
||||
|
||||
// Transform Stage
|
||||
void do_setModelTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setModelTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void initTransform();
|
||||
void killTransform();
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
TransformCamera _transformCamera;
|
||||
GLuint _transformObjectBuffer;
|
||||
GLuint _transformCameraBuffer;
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
TransformCamera _transformCamera;
|
||||
GLuint _transformObjectBuffer;
|
||||
GLuint _transformCameraBuffer;
|
||||
Transform _model;
|
||||
Transform _view;
|
||||
Mat4 _projection;
|
||||
|
@ -253,18 +253,18 @@ protected:
|
|||
|
||||
void do_setStateBlendFactor(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setUniformTexture(Batch& batch, uint32 paramOffset);
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setUniformTexture(Batch& batch, uint32 paramOffset);
|
||||
|
||||
// Standard update pipeline check that the current Program and current State or good to go for a
|
||||
void updatePipeline();
|
||||
// Force to reset all the state fields indicated by the 'toBeReset" signature
|
||||
void updatePipeline();
|
||||
// Force to reset all the state fields indicated by the 'toBeReset" signature
|
||||
void resetPipelineState(State::Signature toBeReset);
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void syncPipelineStateCache();
|
||||
// Grab the actual gl state into it's gpu::State equivalent. THis is used by the above call syncPipleineStateCache()
|
||||
void getCurrentGLState(State::Cache& state);
|
||||
|
||||
|
||||
struct PipelineStageState {
|
||||
|
||||
PipelinePointer _pipeline;
|
||||
|
@ -283,8 +283,8 @@ protected:
|
|||
_pipeline(),
|
||||
_program(0),
|
||||
_invalidProgram(false),
|
||||
_stateSignatureCache(0),
|
||||
_stateCache(State::DEFAULT),
|
||||
_stateSignatureCache(0),
|
||||
_state(nullptr),
|
||||
_invalidState(false),
|
||||
_needStateSync(true)
|
||||
|
@ -294,17 +294,17 @@ protected:
|
|||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
void do_glEnable(Batch& batch, uint32 paramOffset);
|
||||
void do_glEnable(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisable(Batch& batch, uint32 paramOffset);
|
||||
|
||||
|
||||
void do_glEnableClientState(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisableClientState(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glCullFace(Batch& batch, uint32 paramOffset);
|
||||
void do_glAlphaFunc(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glDepthFunc(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthMask(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthFunc(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthMask(Batch& batch, uint32 paramOffset);
|
||||
void do_glDepthRange(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glBindBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
@ -318,7 +318,7 @@ protected:
|
|||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
void do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset);
|
||||
|
|
|
@ -19,7 +19,7 @@ GLBackend::GLState::GLState()
|
|||
|
||||
GLBackend::GLState::~GLState() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef GLBackend::GLState::Command Command;
|
||||
typedef GLBackend::GLState::CommandPointer CommandPointer;
|
||||
|
@ -62,7 +62,7 @@ const GLBackend::GLState::Commands GLBackend::GLState::_resetStateCommands = {
|
|||
CommandPointer(new Command1U(&GLBackend::do_setStateColorWriteMask, State::DEFAULT.colorWriteMask))
|
||||
};
|
||||
|
||||
void generateFillMode(GLBackend::GLState::Commands& commands, State::FillMode fillMode) {
|
||||
void generateFillMode(GLBackend::GLState::Commands& commands, State::FillMode fillMode) {
|
||||
commands.push_back(CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, int32(fillMode))));
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ void generateDepthBias(GLBackend::GLState::Commands& commands, const State& stat
|
|||
commands.push_back(CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(state.getDepthBias(), state.getDepthBiasSlopeScale()))));
|
||||
}
|
||||
|
||||
void generateDepthTest(GLBackend::GLState::Commands& commands, State::DepthTest& test) {
|
||||
void generateDepthTest(GLBackend::GLState::Commands& commands, const State::DepthTest& test) {
|
||||
commands.push_back(CommandPointer(new CommandDepthTest(&GLBackend::do_setStateDepthTest, int32(test.getRaw()))));
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,76 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
|
|||
bool blendState = false;
|
||||
|
||||
// go thorugh the list of state fields in the State and record the corresponding gl command
|
||||
for (int i = 0; i < State::NUM_FIELDS; i++) {
|
||||
if (state.getSignature()[i]) {
|
||||
switch(i) {
|
||||
case State::FILL_MODE: {
|
||||
generateFillMode(object->_commands, state.getFillMode());
|
||||
break;
|
||||
}
|
||||
case State::CULL_MODE: {
|
||||
generateCullMode(object->_commands, state.getCullMode());
|
||||
break;
|
||||
}
|
||||
case State::DEPTH_BIAS:
|
||||
case State::DEPTH_BIAS_SLOPE_SCALE: {
|
||||
depthBias = true;
|
||||
break;
|
||||
}
|
||||
case State::FRONT_FACE_CLOCKWISE: {
|
||||
generateFrontFaceClockwise(object->_commands, state.isFrontFaceClockwise());
|
||||
break;
|
||||
}
|
||||
case State::DEPTH_CLIP_ENABLE: {
|
||||
generateDepthClipEnable(object->_commands, state.isDepthClipEnable());
|
||||
break;
|
||||
}
|
||||
case State::SCISSOR_ENABLE: {
|
||||
generateScissorEnable(object->_commands, state.isScissorEnable());
|
||||
break;
|
||||
}
|
||||
case State::MULTISAMPLE_ENABLE: {
|
||||
generateMultisampleEnable(object->_commands, state.isMultisampleEnable());
|
||||
break;
|
||||
}
|
||||
case State::ANTIALISED_LINE_ENABLE: {
|
||||
generateAntialiasedLineEnable(object->_commands, state.isAntialiasedLineEnable());
|
||||
break;
|
||||
}
|
||||
case State::DEPTH_TEST: {
|
||||
generateDepthTest(object->_commands, state.getDepthTest());
|
||||
break;
|
||||
}
|
||||
|
||||
case State::STENCIL_ACTIVATION:
|
||||
case State::STENCIL_TEST_FRONT:
|
||||
case State::STENCIL_TEST_BACK: {
|
||||
stencilState = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case State::SAMPLE_MASK: {
|
||||
generateSampleMask(object->_commands, state.getSampleMask());
|
||||
break;
|
||||
}
|
||||
case State::ALPHA_TO_COVERAGE_ENABLE: {
|
||||
generateAlphaToCoverageEnable(object->_commands, state.isAlphaToCoverageEnabled());
|
||||
break;
|
||||
}
|
||||
|
||||
case State::BLEND_FUNCTION: {
|
||||
generateBlend(object->_commands, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case State::COLOR_WRITE_MASK: {
|
||||
generateColorWriteMask(object->_commands, state.getColorWriteMask());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (auto field: state.getFields()) {
|
||||
switch(field.first) {
|
||||
case State::FILL_MODE: {
|
||||
|
@ -210,7 +280,7 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
if (depthBias) {
|
||||
generateDepthBias(object->_commands, state);
|
||||
}
|
||||
|
@ -222,7 +292,7 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
|
|||
return object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLBackend::resetPipelineState(State::Signature nextSignature) {
|
||||
auto currentNotSignature = ~_pipeline._stateSignatureCache;
|
||||
auto nextNotSignature = ~nextSignature;
|
||||
|
@ -238,196 +308,199 @@ void GLBackend::resetPipelineState(State::Signature nextSignature) {
|
|||
}
|
||||
|
||||
State::ComparisonFunction comparisonFuncFromGL(GLenum func) {
|
||||
if (func == GL_NEVER) {
|
||||
return State::NEVER;
|
||||
} else if (func == GL_LESS) {
|
||||
return State::LESS;
|
||||
} else if (func == GL_EQUAL) {
|
||||
return State::EQUAL;
|
||||
} else if (func == GL_LEQUAL) {
|
||||
return State::LESS_EQUAL;
|
||||
} else if (func == GL_GREATER) {
|
||||
return State::GREATER;
|
||||
} else if (func == GL_NOTEQUAL) {
|
||||
return State::NOT_EQUAL;
|
||||
} else if (func == GL_GEQUAL) {
|
||||
return State::GREATER_EQUAL;
|
||||
} else if (func == GL_ALWAYS) {
|
||||
return State::ALWAYS;
|
||||
}
|
||||
if (func == GL_NEVER) {
|
||||
return State::NEVER;
|
||||
} else if (func == GL_LESS) {
|
||||
return State::LESS;
|
||||
} else if (func == GL_EQUAL) {
|
||||
return State::EQUAL;
|
||||
} else if (func == GL_LEQUAL) {
|
||||
return State::LESS_EQUAL;
|
||||
} else if (func == GL_GREATER) {
|
||||
return State::GREATER;
|
||||
} else if (func == GL_NOTEQUAL) {
|
||||
return State::NOT_EQUAL;
|
||||
} else if (func == GL_GEQUAL) {
|
||||
return State::GREATER_EQUAL;
|
||||
} else if (func == GL_ALWAYS) {
|
||||
return State::ALWAYS;
|
||||
}
|
||||
|
||||
return State::ALWAYS;
|
||||
}
|
||||
|
||||
State::StencilOp stencilOpFromGL(GLenum stencilOp) {
|
||||
if (stencilOp == GL_KEEP) {
|
||||
return State::STENCIL_OP_KEEP;
|
||||
} else if (stencilOp == GL_ZERO) {
|
||||
return State::STENCIL_OP_ZERO;
|
||||
} else if (stencilOp == GL_REPLACE) {
|
||||
return State::STENCIL_OP_REPLACE;
|
||||
} else if (stencilOp == GL_INCR_WRAP) {
|
||||
return State::STENCIL_OP_INCR_SAT;
|
||||
} else if (stencilOp == GL_DECR_WRAP) {
|
||||
return State::STENCIL_OP_DECR_SAT;
|
||||
} else if (stencilOp == GL_INVERT) {
|
||||
return State::STENCIL_OP_INVERT;
|
||||
} else if (stencilOp == GL_INCR) {
|
||||
return State::STENCIL_OP_INCR;
|
||||
} else if (stencilOp == GL_DECR) {
|
||||
return State::STENCIL_OP_DECR;
|
||||
}
|
||||
|
||||
return State::STENCIL_OP_KEEP;
|
||||
}
|
||||
|
||||
if (stencilOp == GL_KEEP) {
|
||||
return State::STENCIL_OP_KEEP;
|
||||
} else if (stencilOp == GL_ZERO) {
|
||||
return State::STENCIL_OP_ZERO;
|
||||
} else if (stencilOp == GL_REPLACE) {
|
||||
return State::STENCIL_OP_REPLACE;
|
||||
} else if (stencilOp == GL_INCR_WRAP) {
|
||||
return State::STENCIL_OP_INCR_SAT;
|
||||
} else if (stencilOp == GL_DECR_WRAP) {
|
||||
return State::STENCIL_OP_DECR_SAT;
|
||||
} else if (stencilOp == GL_INVERT) {
|
||||
return State::STENCIL_OP_INVERT;
|
||||
} else if (stencilOp == GL_INCR) {
|
||||
return State::STENCIL_OP_INCR;
|
||||
} else if (stencilOp == GL_DECR) {
|
||||
return State::STENCIL_OP_DECR;
|
||||
}
|
||||
|
||||
return State::STENCIL_OP_KEEP;
|
||||
}
|
||||
|
||||
State::BlendOp blendOpFromGL(GLenum blendOp) {
|
||||
if (blendOp == GL_FUNC_ADD) {
|
||||
return State::BLEND_OP_ADD;
|
||||
} else if (blendOp == GL_FUNC_SUBTRACT) {
|
||||
return State::BLEND_OP_SUBTRACT;
|
||||
} else if (blendOp == GL_FUNC_REVERSE_SUBTRACT) {
|
||||
return State::BLEND_OP_REV_SUBTRACT;
|
||||
} else if (blendOp == GL_MIN) {
|
||||
return State::BLEND_OP_MIN;
|
||||
} else if (blendOp == GL_MAX) {
|
||||
return State::BLEND_OP_MAX;
|
||||
}
|
||||
if (blendOp == GL_FUNC_ADD) {
|
||||
return State::BLEND_OP_ADD;
|
||||
} else if (blendOp == GL_FUNC_SUBTRACT) {
|
||||
return State::BLEND_OP_SUBTRACT;
|
||||
} else if (blendOp == GL_FUNC_REVERSE_SUBTRACT) {
|
||||
return State::BLEND_OP_REV_SUBTRACT;
|
||||
} else if (blendOp == GL_MIN) {
|
||||
return State::BLEND_OP_MIN;
|
||||
} else if (blendOp == GL_MAX) {
|
||||
return State::BLEND_OP_MAX;
|
||||
}
|
||||
|
||||
return State::BLEND_OP_ADD;
|
||||
}
|
||||
|
||||
State::BlendArg blendArgFromGL(GLenum blendArg) {
|
||||
if (blendArg == GL_ZERO) {
|
||||
return State::ZERO;
|
||||
} else if (blendArg == GL_ONE) {
|
||||
return State::ONE;
|
||||
} else if (blendArg == GL_SRC_COLOR) {
|
||||
return State::SRC_COLOR;
|
||||
} else if (blendArg == GL_ONE_MINUS_SRC_COLOR) {
|
||||
return State::INV_SRC_COLOR;
|
||||
} else if (blendArg == GL_DST_COLOR) {
|
||||
return State::DEST_COLOR;
|
||||
} else if (blendArg == GL_ONE_MINUS_DST_COLOR) {
|
||||
return State::INV_DEST_COLOR;
|
||||
} else if (blendArg == GL_SRC_ALPHA) {
|
||||
if (blendArg == GL_ZERO) {
|
||||
return State::ZERO;
|
||||
} else if (blendArg == GL_ONE) {
|
||||
return State::ONE;
|
||||
} else if (blendArg == GL_SRC_COLOR) {
|
||||
return State::SRC_COLOR;
|
||||
} else if (blendArg == GL_ONE_MINUS_SRC_COLOR) {
|
||||
return State::INV_SRC_COLOR;
|
||||
} else if (blendArg == GL_DST_COLOR) {
|
||||
return State::DEST_COLOR;
|
||||
} else if (blendArg == GL_ONE_MINUS_DST_COLOR) {
|
||||
return State::INV_DEST_COLOR;
|
||||
} else if (blendArg == GL_SRC_ALPHA) {
|
||||
return State::SRC_ALPHA;
|
||||
} else if (blendArg == GL_ONE_MINUS_SRC_ALPHA) {
|
||||
} else if (blendArg == GL_ONE_MINUS_SRC_ALPHA) {
|
||||
return State::INV_SRC_ALPHA;
|
||||
} else if (blendArg == GL_DST_ALPHA) {
|
||||
} else if (blendArg == GL_DST_ALPHA) {
|
||||
return State::DEST_ALPHA;
|
||||
} else if (blendArg == GL_ONE_MINUS_DST_ALPHA) {
|
||||
} else if (blendArg == GL_ONE_MINUS_DST_ALPHA) {
|
||||
return State::INV_DEST_ALPHA;
|
||||
} else if (blendArg == GL_CONSTANT_COLOR) {
|
||||
} else if (blendArg == GL_CONSTANT_COLOR) {
|
||||
return State::FACTOR_COLOR;
|
||||
} else if (blendArg == GL_ONE_MINUS_CONSTANT_COLOR) {
|
||||
} else if (blendArg == GL_ONE_MINUS_CONSTANT_COLOR) {
|
||||
return State::INV_FACTOR_COLOR;
|
||||
} else if (blendArg == GL_CONSTANT_ALPHA) {
|
||||
} else if (blendArg == GL_CONSTANT_ALPHA) {
|
||||
return State::FACTOR_ALPHA;
|
||||
} else if (blendArg == GL_ONE_MINUS_CONSTANT_ALPHA) {
|
||||
} else if (blendArg == GL_ONE_MINUS_CONSTANT_ALPHA) {
|
||||
return State::INV_FACTOR_ALPHA;
|
||||
}
|
||||
|
||||
return State::ONE;
|
||||
}
|
||||
|
||||
void GLBackend::getCurrentGLState(State::Cache& state) {
|
||||
{
|
||||
GLint modes[2];
|
||||
glGetIntegerv(GL_POLYGON_MODE, modes);
|
||||
if (modes[0] == GL_FILL) {
|
||||
state.fillMode = State::FILL_FACE;
|
||||
} else {
|
||||
if (modes[0] == GL_LINE) {
|
||||
state.fillMode = State::FILL_LINE;
|
||||
} else {
|
||||
state.fillMode = State::FILL_POINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
if (glIsEnabled(GL_CULL_FACE)) {
|
||||
GLint mode;
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &mode);
|
||||
state.cullMode = (mode == GL_FRONT ? State::CULL_FRONT : State::CULL_BACK);
|
||||
} else {
|
||||
state.cullMode = State::CULL_NONE;
|
||||
}
|
||||
}
|
||||
{
|
||||
GLint winding;
|
||||
glGetIntegerv(GL_FRONT_FACE, &winding);
|
||||
state.frontFaceClockwise = (winding == GL_CW);
|
||||
state.depthClipEnable = glIsEnabled(GL_DEPTH_CLAMP);
|
||||
state.scissorEnable = glIsEnabled(GL_SCISSOR_TEST);
|
||||
state.multisampleEnable = glIsEnabled(GL_MULTISAMPLE);
|
||||
state.antialisedLineEnable = glIsEnabled(GL_LINE_SMOOTH);
|
||||
}
|
||||
{
|
||||
if (glIsEnabled(GL_POLYGON_OFFSET_FILL)) {
|
||||
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &state.depthBiasSlopeScale);
|
||||
glGetFloatv(GL_POLYGON_OFFSET_UNITS, &state.depthBias);
|
||||
}
|
||||
}
|
||||
{
|
||||
GLboolean isEnabled = glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean writeMask;
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &writeMask);
|
||||
GLint func;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &func);
|
||||
|
||||
state.depthTest = State::DepthTest(isEnabled, writeMask, comparisonFuncFromGL(func));
|
||||
}
|
||||
{
|
||||
GLboolean isEnabled = glIsEnabled(GL_STENCIL_TEST);
|
||||
|
||||
GLint frontWriteMask;
|
||||
GLint frontReadMask;
|
||||
GLint frontRef;
|
||||
GLint frontFail;
|
||||
GLint frontDepthFail;
|
||||
GLint frontPass;
|
||||
GLint frontFunc;
|
||||
glGetIntegerv(GL_STENCIL_WRITEMASK, &frontWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontReadMask);
|
||||
glGetIntegerv(GL_STENCIL_REF, &frontRef);
|
||||
glGetIntegerv(GL_STENCIL_FAIL, &frontFail);
|
||||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &frontDepthFail);
|
||||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontPass);
|
||||
glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
|
||||
|
||||
GLint backWriteMask;
|
||||
GLint backReadMask;
|
||||
GLint backRef;
|
||||
GLint backFail;
|
||||
GLint backDepthFail;
|
||||
GLint backPass;
|
||||
GLint backFunc;
|
||||
glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backReadMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail);
|
||||
glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &backDepthFail);
|
||||
glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backPass);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
|
||||
|
||||
state.stencilActivation = State::StencilActivation(isEnabled, frontWriteMask, backWriteMask);
|
||||
state.stencilTestFront = State::StencilTest(frontRef, frontReadMask, comparisonFuncFromGL(frontFunc), stencilOpFromGL(frontFail), stencilOpFromGL(frontDepthFail), stencilOpFromGL(frontPass));
|
||||
state.stencilTestBack = State::StencilTest(backRef, backReadMask, comparisonFuncFromGL(backFunc), stencilOpFromGL(backFail), stencilOpFromGL(backDepthFail), stencilOpFromGL(backPass));
|
||||
}
|
||||
{
|
||||
|
||||
void GLBackend::getCurrentGLState(State::Cache& state) {
|
||||
{
|
||||
GLint modes[2];
|
||||
glGetIntegerv(GL_POLYGON_MODE, modes);
|
||||
if (modes[0] == GL_FILL) {
|
||||
state.fillMode = State::FILL_FACE;
|
||||
} else {
|
||||
if (modes[0] == GL_LINE) {
|
||||
state.fillMode = State::FILL_LINE;
|
||||
} else {
|
||||
state.fillMode = State::FILL_POINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
if (glIsEnabled(GL_CULL_FACE)) {
|
||||
GLint mode;
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &mode);
|
||||
state.cullMode = (mode == GL_FRONT ? State::CULL_FRONT : State::CULL_BACK);
|
||||
} else {
|
||||
state.cullMode = State::CULL_NONE;
|
||||
}
|
||||
}
|
||||
{
|
||||
GLint winding;
|
||||
glGetIntegerv(GL_FRONT_FACE, &winding);
|
||||
state.frontFaceClockwise = (winding == GL_CW);
|
||||
state.depthClipEnable = glIsEnabled(GL_DEPTH_CLAMP);
|
||||
state.scissorEnable = glIsEnabled(GL_SCISSOR_TEST);
|
||||
state.multisampleEnable = glIsEnabled(GL_MULTISAMPLE);
|
||||
state.antialisedLineEnable = glIsEnabled(GL_LINE_SMOOTH);
|
||||
}
|
||||
{
|
||||
if (glIsEnabled(GL_POLYGON_OFFSET_FILL)) {
|
||||
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &state.depthBiasSlopeScale);
|
||||
glGetFloatv(GL_POLYGON_OFFSET_UNITS, &state.depthBias);
|
||||
}
|
||||
}
|
||||
{
|
||||
GLboolean isEnabled = glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean writeMask;
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &writeMask);
|
||||
GLint func;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &func);
|
||||
|
||||
state.depthTest = State::DepthTest(isEnabled, writeMask, comparisonFuncFromGL(func));
|
||||
}
|
||||
{
|
||||
GLboolean isEnabled = glIsEnabled(GL_STENCIL_TEST);
|
||||
|
||||
GLint frontWriteMask;
|
||||
GLint frontReadMask;
|
||||
GLint frontRef;
|
||||
GLint frontFail;
|
||||
GLint frontDepthFail;
|
||||
GLint frontPass;
|
||||
GLint frontFunc;
|
||||
glGetIntegerv(GL_STENCIL_WRITEMASK, &frontWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontReadMask);
|
||||
glGetIntegerv(GL_STENCIL_REF, &frontRef);
|
||||
glGetIntegerv(GL_STENCIL_FAIL, &frontFail);
|
||||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &frontDepthFail);
|
||||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontPass);
|
||||
glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
|
||||
|
||||
GLint backWriteMask;
|
||||
GLint backReadMask;
|
||||
GLint backRef;
|
||||
GLint backFail;
|
||||
GLint backDepthFail;
|
||||
GLint backPass;
|
||||
GLint backFunc;
|
||||
glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backReadMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail);
|
||||
glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &backDepthFail);
|
||||
glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backPass);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
|
||||
|
||||
state.stencilActivation = State::StencilActivation(isEnabled, frontWriteMask, backWriteMask);
|
||||
state.stencilTestFront = State::StencilTest(frontRef, frontReadMask, comparisonFuncFromGL(frontFunc), stencilOpFromGL(frontFail), stencilOpFromGL(frontDepthFail), stencilOpFromGL(frontPass));
|
||||
state.stencilTestBack = State::StencilTest(backRef, backReadMask, comparisonFuncFromGL(backFunc), stencilOpFromGL(backFail), stencilOpFromGL(backDepthFail), stencilOpFromGL(backPass));
|
||||
}
|
||||
{
|
||||
GLint mask = 0xFFFFFFFF;
|
||||
if (glIsEnabled(GL_SAMPLE_MASK)) {
|
||||
glGetIntegerv(GL_SAMPLE_MASK, &mask);
|
||||
state.sampleMask = mask;
|
||||
}
|
||||
state.sampleMask = mask;
|
||||
}
|
||||
{
|
||||
|
||||
#ifdef GPU_PROFILE_CORE
|
||||
if (glIsEnabled(GL_SAMPLE_MASK)) {
|
||||
glGetIntegerv(GL_SAMPLE_MASK, &mask);
|
||||
state.sampleMask = mask;
|
||||
}
|
||||
#endif
|
||||
state.sampleMask = mask;
|
||||
}
|
||||
{
|
||||
state.alphaToCoverageEnable = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||
}
|
||||
{
|
||||
GLboolean isEnabled = glIsEnabled(GL_BLEND);
|
||||
GLboolean isEnabled = glIsEnabled(GL_BLEND);
|
||||
GLint srcRGB;
|
||||
GLint srcA;
|
||||
GLint dstRGB;
|
||||
|
@ -448,34 +521,34 @@ void GLBackend::getCurrentGLState(State::Cache& state) {
|
|||
}
|
||||
{
|
||||
GLboolean mask[4];
|
||||
glGetBooleanv(GL_COLOR_WRITEMASK, mask);
|
||||
state.colorWriteMask = (mask[0] ? State::WRITE_RED : 0)
|
||||
| (mask[1] ? State::WRITE_GREEN : 0)
|
||||
| (mask[2] ? State::WRITE_BLUE : 0)
|
||||
glGetBooleanv(GL_COLOR_WRITEMASK, mask);
|
||||
state.colorWriteMask = (mask[0] ? State::WRITE_RED : 0)
|
||||
| (mask[1] ? State::WRITE_GREEN : 0)
|
||||
| (mask[2] ? State::WRITE_BLUE : 0)
|
||||
| (mask[3] ? State::WRITE_ALPHA : 0);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::syncPipelineStateCache() {
|
||||
State::Cache state;
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
getCurrentGLState(state);
|
||||
State::Signature signature = State::evalSignature(state);
|
||||
|
||||
_pipeline._stateCache = state;
|
||||
_pipeline._stateSignatureCache = signature;
|
||||
}
|
||||
|
||||
static GLenum GL_COMPARISON_FUNCTIONS[] = {
|
||||
GL_NEVER,
|
||||
GL_LESS,
|
||||
GL_EQUAL,
|
||||
GL_LEQUAL,
|
||||
GL_GREATER,
|
||||
GL_NOTEQUAL,
|
||||
GL_GEQUAL,
|
||||
void GLBackend::syncPipelineStateCache() {
|
||||
State::Cache state;
|
||||
|
||||
getCurrentGLState(state);
|
||||
State::Signature signature = State::evalSignature(state);
|
||||
|
||||
_pipeline._stateCache = state;
|
||||
_pipeline._stateSignatureCache = signature;
|
||||
}
|
||||
|
||||
static GLenum GL_COMPARISON_FUNCTIONS[] = {
|
||||
GL_NEVER,
|
||||
GL_LESS,
|
||||
GL_EQUAL,
|
||||
GL_LEQUAL,
|
||||
GL_GREATER,
|
||||
GL_NOTEQUAL,
|
||||
GL_GEQUAL,
|
||||
GL_ALWAYS };
|
||||
|
||||
void GLBackend::do_setStateFillMode(int32 mode) {
|
||||
|
@ -488,15 +561,15 @@ void GLBackend::do_setStateFillMode(int32 mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setStateCullMode(int32 mode) {
|
||||
void GLBackend::do_setStateCullMode(int32 mode) {
|
||||
if (_pipeline._stateCache.cullMode != mode) {
|
||||
static GLenum GL_CULL_MODES[] = { GL_FRONT_AND_BACK, GL_FRONT, GL_BACK };
|
||||
if (mode == State::CULL_NONE) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT_AND_BACK);
|
||||
} else {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_CULL_MODES[mode]);
|
||||
static GLenum GL_CULL_MODES[] = { GL_FRONT_AND_BACK, GL_FRONT, GL_BACK };
|
||||
if (mode == State::CULL_NONE) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT_AND_BACK);
|
||||
} else {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_CULL_MODES[mode]);
|
||||
}
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
|
@ -587,12 +660,12 @@ void GLBackend::do_setStateDepthBias(Vec2 bias) {
|
|||
|
||||
void GLBackend::do_setStateDepthTest(State::DepthTest test) {
|
||||
if (_pipeline._stateCache.depthTest != test) {
|
||||
if (test.isEnabled()) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
if (test.isEnabled()) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(test.getWriteMask());
|
||||
glDepthFunc(GL_COMPARISON_FUNCTIONS[test.getFunction()]);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
|
@ -611,14 +684,14 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S
|
|||
glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront());
|
||||
glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack());
|
||||
|
||||
static GLenum STENCIL_OPS[] = {
|
||||
GL_KEEP,
|
||||
GL_ZERO,
|
||||
GL_REPLACE,
|
||||
GL_INCR_WRAP,
|
||||
GL_DECR_WRAP,
|
||||
GL_INVERT,
|
||||
GL_INCR,
|
||||
static GLenum STENCIL_OPS[] = {
|
||||
GL_KEEP,
|
||||
GL_ZERO,
|
||||
GL_REPLACE,
|
||||
GL_INCR_WRAP,
|
||||
GL_DECR_WRAP,
|
||||
GL_INVERT,
|
||||
GL_INCR,
|
||||
GL_DECR };
|
||||
|
||||
glStencilFuncSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]);
|
||||
|
@ -651,12 +724,14 @@ void GLBackend::do_setStateAlphaToCoverageEnable(bool enable) {
|
|||
|
||||
void GLBackend::do_setStateSampleMask(uint32 mask) {
|
||||
if (_pipeline._stateCache.sampleMask != mask) {
|
||||
#ifdef GPU_CORE_PROFILE
|
||||
if (mask == 0xFFFFFFFF) {
|
||||
glDisable(GL_SAMPLE_MASK);
|
||||
} else {
|
||||
glEnable(GL_SAMPLE_MASK);
|
||||
glSampleMaski(0, mask);
|
||||
}
|
||||
#endif
|
||||
_pipeline._stateCache.sampleMask = mask;
|
||||
}
|
||||
}
|
||||
|
@ -666,35 +741,35 @@ void GLBackend::do_setStateBlend(State::BlendFunction function) {
|
|||
if (function.isEnabled()) {
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
static GLenum GL_BLEND_OPS[] = {
|
||||
GL_FUNC_ADD,
|
||||
GL_FUNC_SUBTRACT,
|
||||
GL_FUNC_REVERSE_SUBTRACT,
|
||||
GL_MIN,
|
||||
GL_MAX };
|
||||
static GLenum GL_BLEND_OPS[] = {
|
||||
GL_FUNC_ADD,
|
||||
GL_FUNC_SUBTRACT,
|
||||
GL_FUNC_REVERSE_SUBTRACT,
|
||||
GL_MIN,
|
||||
GL_MAX };
|
||||
|
||||
glBlendEquationSeparate(GL_BLEND_OPS[function.getOperationColor()], GL_BLEND_OPS[function.getOperationAlpha()]);
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
static GLenum BLEND_ARGS[] = {
|
||||
GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_SRC_COLOR,
|
||||
GL_ONE_MINUS_SRC_COLOR,
|
||||
GL_SRC_ALPHA,
|
||||
GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA,
|
||||
GL_DST_COLOR,
|
||||
GL_ONE_MINUS_DST_COLOR,
|
||||
GL_SRC_ALPHA_SATURATE,
|
||||
GL_CONSTANT_COLOR,
|
||||
GL_ONE_MINUS_CONSTANT_COLOR,
|
||||
GL_CONSTANT_ALPHA,
|
||||
GL_ONE_MINUS_CONSTANT_ALPHA,
|
||||
};
|
||||
static GLenum BLEND_ARGS[] = {
|
||||
GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_SRC_COLOR,
|
||||
GL_ONE_MINUS_SRC_COLOR,
|
||||
GL_SRC_ALPHA,
|
||||
GL_ONE_MINUS_SRC_ALPHA,
|
||||
GL_DST_ALPHA,
|
||||
GL_ONE_MINUS_DST_ALPHA,
|
||||
GL_DST_COLOR,
|
||||
GL_ONE_MINUS_DST_COLOR,
|
||||
GL_SRC_ALPHA_SATURATE,
|
||||
GL_CONSTANT_COLOR,
|
||||
GL_ONE_MINUS_CONSTANT_COLOR,
|
||||
GL_CONSTANT_ALPHA,
|
||||
GL_ONE_MINUS_CONSTANT_ALPHA,
|
||||
};
|
||||
|
||||
glBlendFuncSeparate(BLEND_ARGS[function.getSourceColor()], BLEND_ARGS[function.getDestinationColor()],
|
||||
glBlendFuncSeparate(BLEND_ARGS[function.getSourceColor()], BLEND_ARGS[function.getDestinationColor()],
|
||||
BLEND_ARGS[function.getSourceAlpha()], BLEND_ARGS[function.getDestinationAlpha()]);
|
||||
CHECK_GL_ERROR();
|
||||
} else {
|
||||
|
|
|
@ -1,33 +1,34 @@
|
|||
//
|
||||
// Pipeline.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 3/8/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_State_h
|
||||
#define hifi_gpu_State_h
|
||||
|
||||
#include "Format.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <bitset>
|
||||
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class GPUObject;
|
||||
|
||||
class State {
|
||||
public:
|
||||
State();
|
||||
virtual ~State();
|
||||
|
||||
const Stamp getStamp() const { return _stamp; }
|
||||
//
|
||||
// State
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 3/8/2015.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_gpu_State_h
|
||||
#define hifi_gpu_State_h
|
||||
|
||||
#include "Format.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <bitset>
|
||||
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class GPUObject;
|
||||
|
||||
class State {
|
||||
public:
|
||||
State();
|
||||
virtual ~State();
|
||||
|
||||
const Stamp getStamp() const { return _stamp; }
|
||||
|
||||
enum ComparisonFunction {
|
||||
NEVER = 0,
|
||||
|
@ -57,7 +58,7 @@ public:
|
|||
|
||||
NUM_CULL_MODES,
|
||||
};
|
||||
|
||||
|
||||
enum StencilOp {
|
||||
STENCIL_OP_KEEP = 0,
|
||||
STENCIL_OP_ZERO,
|
||||
|
@ -69,8 +70,8 @@ public:
|
|||
STENCIL_OP_DECR,
|
||||
|
||||
NUM_STENCIL_OPS,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum BlendArg {
|
||||
ZERO = 0,
|
||||
ONE,
|
||||
|
@ -110,152 +111,228 @@ public:
|
|||
WRITE_ALPHA = 8,
|
||||
WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ),
|
||||
};
|
||||
|
||||
class DepthTest {
|
||||
uint8 _function = LESS;
|
||||
bool _writeMask = true;
|
||||
bool _enabled = false;
|
||||
public:
|
||||
DepthTest(bool enabled, bool writeMask, ComparisonFunction func) :
|
||||
_function(func), _writeMask(writeMask), _enabled(enabled) {}
|
||||
|
||||
bool isEnabled() const { return _enabled; }
|
||||
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
||||
bool getWriteMask() const { return _writeMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const DepthTest& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const DepthTest& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
|
||||
class DepthTest {
|
||||
uint8 _function = LESS;
|
||||
bool _writeMask = true;
|
||||
bool _enabled = false;
|
||||
public:
|
||||
DepthTest(bool enabled, bool writeMask, ComparisonFunction func) :
|
||||
_function(func), _writeMask(writeMask), _enabled(enabled) {}
|
||||
|
||||
bool isEnabled() const { return _enabled; }
|
||||
ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
|
||||
bool getWriteMask() const { return _writeMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const DepthTest& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const DepthTest& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
class StencilTest {
|
||||
static const int FUNC_MASK = 0x000f;
|
||||
static const int FAIL_OP_MASK = 0x00f0;
|
||||
static const int DEPTH_FAIL_OP_MASK = 0x0f00;
|
||||
static const int PASS_OP_MASK = 0xf000;
|
||||
static const int FAIL_OP_MASK = 0x00f0;
|
||||
static const int DEPTH_FAIL_OP_MASK = 0x0f00;
|
||||
static const int PASS_OP_MASK = 0xf000;
|
||||
static const int FAIL_OP_OFFSET = 4;
|
||||
static const int DEPTH_FAIL_OP_OFFSET = 8;
|
||||
static const int PASS_OP_OFFSET = 12;
|
||||
|
||||
uint16 _functionAndOperations;
|
||||
uint8 _reference = 0;
|
||||
uint8 _readMask = 0xff;
|
||||
public:
|
||||
|
||||
StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) :
|
||||
_reference(reference), _readMask(readMask),
|
||||
_functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)) {}
|
||||
|
||||
ComparisonFunction getFunction() const { return ComparisonFunction(_functionAndOperations & FUNC_MASK); }
|
||||
StencilOp getFailOp() const { return StencilOp((_functionAndOperations & FAIL_OP_MASK) >> FAIL_OP_OFFSET); }
|
||||
StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); }
|
||||
StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); }
|
||||
|
||||
uint8 getReference() const { return _reference; }
|
||||
uint8 getReadMask() const { return _readMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
StencilTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const StencilTest& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const StencilTest& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
class StencilActivation {
|
||||
uint8 _frontWriteMask = 0xFF;
|
||||
uint8 _backWriteMask = 0xFF;
|
||||
uint16 _enabled = 0;
|
||||
public:
|
||||
|
||||
StencilActivation(bool enabled, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) :
|
||||
_frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {}
|
||||
|
||||
bool isEnabled() const { return (_enabled != 0); }
|
||||
uint8 getWriteMaskFront() const { return _frontWriteMask; }
|
||||
uint8 getWriteMaskBack() const { return _backWriteMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
StencilActivation(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const StencilActivation& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const StencilActivation& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
class BlendFunction {
|
||||
static const int PASS_OP_OFFSET = 12;
|
||||
|
||||
uint16 _functionAndOperations;
|
||||
uint8 _reference = 0;
|
||||
uint8 _readMask = 0xff;
|
||||
public:
|
||||
|
||||
StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) :
|
||||
_functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)),
|
||||
_reference(reference), _readMask(readMask)
|
||||
{}
|
||||
|
||||
ComparisonFunction getFunction() const { return ComparisonFunction(_functionAndOperations & FUNC_MASK); }
|
||||
StencilOp getFailOp() const { return StencilOp((_functionAndOperations & FAIL_OP_MASK) >> FAIL_OP_OFFSET); }
|
||||
StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); }
|
||||
StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); }
|
||||
|
||||
uint8 getReference() const { return _reference; }
|
||||
uint8 getReadMask() const { return _readMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
StencilTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const StencilTest& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const StencilTest& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
class StencilActivation {
|
||||
uint8 _frontWriteMask = 0xFF;
|
||||
uint8 _backWriteMask = 0xFF;
|
||||
uint16 _enabled = 0;
|
||||
public:
|
||||
|
||||
StencilActivation(bool enabled, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) :
|
||||
_frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {}
|
||||
|
||||
bool isEnabled() const { return (_enabled != 0); }
|
||||
uint8 getWriteMaskFront() const { return _frontWriteMask; }
|
||||
uint8 getWriteMaskBack() const { return _backWriteMask; }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
StencilActivation(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const StencilActivation& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const StencilActivation& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
class BlendFunction {
|
||||
static const int COLOR_MASK = 0x0f;
|
||||
static const int ALPHA_MASK = 0xf0;
|
||||
static const int ALPHA_MASK = 0xf0;
|
||||
static const int ALPHA_OFFSET = 4;
|
||||
|
||||
uint8 _enabled;
|
||||
|
||||
uint8 _enabled;
|
||||
uint8 _source;
|
||||
uint8 _destination;
|
||||
uint8 _destination;
|
||||
uint8 _operation;
|
||||
public:
|
||||
|
||||
BlendFunction(bool enabled,
|
||||
BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor,
|
||||
BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) :
|
||||
_enabled(enabled),
|
||||
_source(sourceColor | (sourceAlpha << ALPHA_OFFSET)),
|
||||
_destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)),
|
||||
_operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {}
|
||||
|
||||
BlendFunction(bool enabled, BlendArg source = ONE, BlendOp operation = BLEND_OP_ADD, BlendArg destination = ZERO) :
|
||||
_enabled(enabled),
|
||||
_source(source | (source << ALPHA_OFFSET)),
|
||||
_destination(destination | (destination << ALPHA_OFFSET)),
|
||||
_operation(operation | (operation << ALPHA_OFFSET)) {}
|
||||
|
||||
bool isEnabled() const { return (_enabled != 0); }
|
||||
|
||||
BlendArg getSourceColor() const { return BlendArg(_source & COLOR_MASK); }
|
||||
BlendArg getDestinationColor() const { return BlendArg(_destination & COLOR_MASK); }
|
||||
BlendOp getOperationColor() const { return BlendOp(_operation & COLOR_MASK); }
|
||||
|
||||
BlendArg getSourceAlpha() const { return BlendArg((_source & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
BlendArg getDestinationAlpha() const { return BlendArg((_destination & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
BlendOp getOperationAlpha() const { return BlendOp((_operation & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
BlendFunction(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const BlendFunction& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const BlendFunction& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
// The Cache class is the full explicit description of the State class fields value.
|
||||
// Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value
|
||||
class Cache {
|
||||
public:
|
||||
FillMode fillMode = FILL_FACE;
|
||||
CullMode cullMode = CULL_NONE;
|
||||
bool frontFaceClockwise = false;
|
||||
bool depthClipEnable = false;
|
||||
bool scissorEnable = false;
|
||||
bool multisampleEnable = false;
|
||||
bool antialisedLineEnable = false;
|
||||
|
||||
float depthBias = 0.0f;
|
||||
float depthBiasSlopeScale = 0.0f;
|
||||
|
||||
DepthTest depthTest = DepthTest(false, true, LESS);
|
||||
|
||||
StencilActivation stencilActivation = StencilActivation(false);
|
||||
StencilTest stencilTestFront = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
||||
StencilTest stencilTestBack = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
||||
|
||||
uint32 sampleMask = 0xFFFFFFFF;
|
||||
bool alphaToCoverageEnable = false;
|
||||
|
||||
BlendFunction blendFunction = BlendFunction(false);
|
||||
|
||||
uint32 colorWriteMask = WRITE_ALL;
|
||||
};
|
||||
|
||||
// The unique default values for all the fields
|
||||
static const Cache DEFAULT;
|
||||
|
||||
BlendFunction(bool enabled,
|
||||
BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor,
|
||||
BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) :
|
||||
_enabled(enabled),
|
||||
_source(sourceColor | (sourceAlpha << ALPHA_OFFSET)),
|
||||
_destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)),
|
||||
_operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {}
|
||||
|
||||
BlendFunction(bool enabled, BlendArg source = ONE, BlendOp operation = BLEND_OP_ADD, BlendArg destination = ZERO) :
|
||||
_enabled(enabled),
|
||||
_source(source | (source << ALPHA_OFFSET)),
|
||||
_destination(destination | (destination << ALPHA_OFFSET)),
|
||||
_operation(operation | (operation << ALPHA_OFFSET)) {}
|
||||
|
||||
bool isEnabled() const { return (_enabled != 0); }
|
||||
|
||||
BlendArg getSourceColor() const { return BlendArg(_source & COLOR_MASK); }
|
||||
BlendArg getDestinationColor() const { return BlendArg(_destination & COLOR_MASK); }
|
||||
BlendOp getOperationColor() const { return BlendOp(_operation & COLOR_MASK); }
|
||||
|
||||
BlendArg getSourceAlpha() const { return BlendArg((_source & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
BlendArg getDestinationAlpha() const { return BlendArg((_destination & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
BlendOp getOperationAlpha() const { return BlendOp((_operation & ALPHA_MASK) >> ALPHA_OFFSET); }
|
||||
|
||||
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||
BlendFunction(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||
bool operator== (const BlendFunction& right) const { return getRaw() == right.getRaw(); }
|
||||
bool operator!= (const BlendFunction& right) const { return getRaw() != right.getRaw(); }
|
||||
};
|
||||
|
||||
// The Cache class is the full explicit description of the State class fields value.
|
||||
// Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value
|
||||
class Cache {
|
||||
public:
|
||||
FillMode fillMode = FILL_FACE;
|
||||
CullMode cullMode = CULL_NONE;
|
||||
bool frontFaceClockwise = false;
|
||||
bool depthClipEnable = false;
|
||||
bool scissorEnable = false;
|
||||
bool multisampleEnable = false;
|
||||
bool antialisedLineEnable = false;
|
||||
|
||||
float depthBias = 0.0f;
|
||||
float depthBiasSlopeScale = 0.0f;
|
||||
|
||||
DepthTest depthTest = DepthTest(false, true, LESS);
|
||||
|
||||
StencilActivation stencilActivation = StencilActivation(false);
|
||||
StencilTest stencilTestFront = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
||||
StencilTest stencilTestBack = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
||||
|
||||
uint32 sampleMask = 0xFFFFFFFF;
|
||||
bool alphaToCoverageEnable = false;
|
||||
|
||||
BlendFunction blendFunction = BlendFunction(false);
|
||||
|
||||
uint32 colorWriteMask = WRITE_ALL;
|
||||
};
|
||||
|
||||
// The unique default values for all the fields
|
||||
static const Cache DEFAULT;
|
||||
void setFillMode(FillMode fill) { set(FILL_MODE, DEFAULT.fillMode, fill, _values.fillMode); }
|
||||
FillMode getFillMode() const { return _values.fillMode; }
|
||||
|
||||
void setCullMode(CullMode cull) { set(CULL_MODE, DEFAULT.cullMode, cull, _values.cullMode); }
|
||||
CullMode getCullMode() const { return _values.cullMode; }
|
||||
|
||||
void setFrontFaceClockwise(bool isClockwise) { set(FRONT_FACE_CLOCKWISE, DEFAULT.frontFaceClockwise, isClockwise, _values.frontFaceClockwise); }
|
||||
bool isFrontFaceClockwise() const { return _values.frontFaceClockwise; }
|
||||
|
||||
void setDepthClipEnable(bool enable) { set(DEPTH_CLIP_ENABLE, DEFAULT.depthClipEnable, enable, _values.depthClipEnable); }
|
||||
bool isDepthClipEnable() const { return _values.depthClipEnable; }
|
||||
|
||||
void setScissorEnable(bool enable) { set(SCISSOR_ENABLE, DEFAULT.scissorEnable, enable, _values.scissorEnable); }
|
||||
bool isScissorEnable() const { return _values.scissorEnable; }
|
||||
|
||||
void setMultisampleEnable(bool enable) { set(MULTISAMPLE_ENABLE, DEFAULT.multisampleEnable, enable, _values.multisampleEnable); }
|
||||
bool isMultisampleEnable() const { return _values.multisampleEnable; }
|
||||
|
||||
void setAntialiasedLineEnable(bool enable) { set(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable, enable, _values.antialisedLineEnable); }
|
||||
bool isAntialiasedLineEnable() const { return _values.antialisedLineEnable; }
|
||||
|
||||
// Depth Bias
|
||||
void setDepthBias(float bias) { set(DEPTH_BIAS, DEFAULT.depthBias, bias, _values.depthBias); }
|
||||
float getDepthBias() const { return _values.depthBias; }
|
||||
|
||||
void setDepthBiasSlopeScale(float scale) { set(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale, scale, _values.depthBiasSlopeScale); }
|
||||
float getDepthBiasSlopeScale() const { return _values.depthBiasSlopeScale; }
|
||||
|
||||
// Depth Test
|
||||
void setDepthTest(DepthTest depthTest) { set(DEPTH_TEST, DEFAULT.depthTest, depthTest, _values.depthTest); }
|
||||
void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { setDepthTest(DepthTest(enable, writeMask, func)); }
|
||||
DepthTest getDepthTest() const { return _values.depthTest; }
|
||||
|
||||
bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); }
|
||||
bool getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); }
|
||||
ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); }
|
||||
|
||||
// Stencil test
|
||||
void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest, uint8 backWriteMask, StencilTest backTest) {
|
||||
set(STENCIL_ACTIVATION, DEFAULT.stencilActivation, StencilActivation(enabled, frontWriteMask, backWriteMask), _values.stencilActivation);
|
||||
set(STENCIL_TEST_FRONT, DEFAULT.stencilTestFront, frontTest, _values.stencilTestFront);
|
||||
set(STENCIL_TEST_BACK, DEFAULT.stencilTestBack, backTest, _values.stencilTestBack); }
|
||||
void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest) {
|
||||
setStencilTest(enabled, frontWriteMask, frontTest, frontWriteMask, frontTest); }
|
||||
|
||||
StencilActivation getStencilActivation() const { return _values.stencilActivation; }
|
||||
StencilTest getStencilTestFront() const { return _values.stencilTestFront; }
|
||||
StencilTest getStencilTestBack() const { return _values.stencilTestBack; }
|
||||
|
||||
bool isStencilEnabled() const { return getStencilActivation().isEnabled(); }
|
||||
uint8 getStencilWriteMaskFront() const { return getStencilActivation().getWriteMaskFront(); }
|
||||
uint8 getStencilWriteMaskBack() const { return getStencilActivation().getWriteMaskBack(); }
|
||||
|
||||
// Alpha to coverage
|
||||
void setAlphaToCoverageEnable(bool enable) { set(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable, _values.alphaToCoverageEnable); }
|
||||
bool isAlphaToCoverageEnabled() const { return _values.alphaToCoverageEnable; }
|
||||
|
||||
// Sample mask
|
||||
void setSampleMask(uint32 mask) { set(SAMPLE_MASK, DEFAULT.sampleMask, mask, _values.sampleMask); }
|
||||
uint32 getSampleMask() const { return _values.sampleMask; }
|
||||
|
||||
// Blend Function
|
||||
void setBlendFunction(BlendFunction function) { set(BLEND_FUNCTION, DEFAULT.blendFunction, function, _values.blendFunction); }
|
||||
BlendFunction getBlendFunction() const { return _values.blendFunction; }
|
||||
|
||||
void setBlendFunction(bool enabled, BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) {
|
||||
setBlendFunction(BlendFunction(enabled, sourceColor, operationColor, destinationColor, sourceAlpha, operationAlpha, destinationAlpha)); }
|
||||
void setBlendFunction(bool enabled, BlendArg source, BlendOp operation, BlendArg destination) {
|
||||
setBlendFunction(BlendFunction(enabled, source, operation, destination)); }
|
||||
|
||||
bool isBlendEnabled() const { return getBlendFunction().isEnabled(); }
|
||||
|
||||
// Color write mask
|
||||
void setColorWriteMask(int32 mask) { set<uint32>(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, mask, _values.colorWriteMask); }
|
||||
uint32 getColorWriteMask() const { return _values.colorWriteMask; }
|
||||
/*
|
||||
void setFillMode(FillMode fill) { set(FILL_MODE, DEFAULT.fillMode, fill); }
|
||||
FillMode getFillMode() const { return get(FILL_MODE, DEFAULT.fillMode); }
|
||||
|
||||
|
||||
void setCullMode(CullMode cull) { set(CULL_MODE, DEFAULT.cullMode, cull); }
|
||||
CullMode getCullMode() const { return get(CULL_MODE, DEFAULT.cullMode); }
|
||||
|
||||
|
@ -273,14 +350,14 @@ public:
|
|||
|
||||
void setAntialiasedLineEnable(bool enable) { set(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable, enable); }
|
||||
bool isAntialiasedLineEnable() const { return get(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable); }
|
||||
|
||||
// Depth Bias
|
||||
|
||||
// Depth Bias
|
||||
void setDepthBias(float bias) { set(DEPTH_BIAS, DEFAULT.depthBias, bias); }
|
||||
float getDepthBias() const { return get(DEPTH_BIAS, DEFAULT.depthBias); }
|
||||
|
||||
void setDepthBiasSlopeScale(float scale) { set(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale, scale); }
|
||||
float getDepthBiasSlopeScale() const { return get(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale); }
|
||||
|
||||
|
||||
// Depth Test
|
||||
void setDepthTest(DepthTest depthTest) { set(DEPTH_TEST, DEFAULT.depthTest, depthTest); }
|
||||
void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { setDepthTest(DepthTest(enable, writeMask, func)); }
|
||||
|
@ -307,7 +384,7 @@ public:
|
|||
uint8 getStencilWriteMaskBack() const { return getStencilActivation().getWriteMaskBack(); }
|
||||
|
||||
// Alpha to coverage
|
||||
void setAlphaToCoverageEnable(bool enable) { set(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable); }
|
||||
void setAlphaToCoverageEnable(bool enable) { set(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable); }
|
||||
bool isAlphaToCoverageEnabled() const { return get(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable); }
|
||||
|
||||
// Sample mask
|
||||
|
@ -323,124 +400,138 @@ public:
|
|||
void setBlendFunction(bool enabled, BlendArg source, BlendOp operation, BlendArg destination) {
|
||||
setBlendFunction(BlendFunction(enabled, source, operation, destination)); }
|
||||
|
||||
bool isBlendEnabled() const { return getBlendFunction().isEnabled(); }
|
||||
|
||||
bool isBlendEnabled() const { return getBlendFunction().isEnabled(); }
|
||||
|
||||
// Color write mask
|
||||
void setColorWriteMask(int32 mask) { set<uint32>(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, mask); }
|
||||
uint32 getColorWriteMask() const { return get<uint32>(COLOR_WRITE_MASK, DEFAULT.colorWriteMask); }
|
||||
|
||||
// The state values are stored in a Map called FieldMap
|
||||
// only the fields with non default value are saved
|
||||
|
||||
// All the possible fields
|
||||
enum Field {
|
||||
FILL_MODE,
|
||||
CULL_MODE,
|
||||
FRONT_FACE_CLOCKWISE,
|
||||
DEPTH_CLIP_ENABLE,
|
||||
SCISSOR_ENABLE,
|
||||
MULTISAMPLE_ENABLE,
|
||||
ANTIALISED_LINE_ENABLE,
|
||||
|
||||
DEPTH_BIAS,
|
||||
DEPTH_BIAS_SLOPE_SCALE,
|
||||
|
||||
DEPTH_TEST,
|
||||
|
||||
STENCIL_ACTIVATION,
|
||||
STENCIL_TEST_FRONT,
|
||||
STENCIL_TEST_BACK,
|
||||
|
||||
SAMPLE_MASK,
|
||||
ALPHA_TO_COVERAGE_ENABLE,
|
||||
|
||||
BLEND_FUNCTION,
|
||||
|
||||
COLOR_WRITE_MASK,
|
||||
|
||||
NUM_FIELDS, // not a valid field, just the count
|
||||
};
|
||||
|
||||
// the value of a field
|
||||
class Value {
|
||||
public:
|
||||
union {
|
||||
uint32 _unsigned_integer = 0;
|
||||
int32 _integer;
|
||||
float _float;
|
||||
};
|
||||
|
||||
template <typename T> void uncast(T v) { _integer = v; }
|
||||
template <> void State::Value::uncast<int>(int v) { _integer = v; }
|
||||
template <> void State::Value::uncast<float>(float v) { _float = v; }
|
||||
template <> void State::Value::uncast<unsigned int>(unsigned int v) { _unsigned_integer = v; }
|
||||
template <> void State::Value::uncast<DepthTest>(DepthTest v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<StencilActivation>(StencilActivation v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<StencilTest>(StencilTest v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<BlendFunction>(BlendFunction v) { _integer = v.getRaw(); }
|
||||
|
||||
template <typename T> T cast() const;
|
||||
template <> int State::Value::cast<int>() const { return _integer; }
|
||||
template <> float State::Value::cast<float>() const { return _float; }
|
||||
template <> unsigned int State::Value::cast<unsigned int>() const { return _unsigned_integer; }
|
||||
template <> DepthTest State::Value::cast<DepthTest>() const { return DepthTest(_integer); }
|
||||
template <> StencilActivation State::Value::cast<StencilActivation>() const { return StencilActivation(_integer); }
|
||||
template <> StencilTest State::Value::cast<StencilTest>() const { return StencilTest(_integer); }
|
||||
template <> BlendFunction State::Value::cast<BlendFunction>() const { return BlendFunction(_integer); }
|
||||
};
|
||||
|
||||
// The field map type
|
||||
typedef std::unordered_map<Field, Value> FieldMap;
|
||||
|
||||
const FieldMap& getFields() const { return _fields; }
|
||||
|
||||
// The signature of the state tells which fields of the state are not default
|
||||
// this way during rendering the Backend can compare it's current state and try to minimize the job to do
|
||||
typedef std::bitset<NUM_FIELDS> Signature;
|
||||
|
||||
Signature getSignature() const { return _signature; }
|
||||
|
||||
static Signature evalSignature(const Cache& state);
|
||||
|
||||
protected:
|
||||
State(const State& state);
|
||||
State& operator=(const State& state);
|
||||
|
||||
template <class T> void set(Field field, T defaultValue, T value) {
|
||||
if (value == defaultValue) {
|
||||
_fields.erase(field);
|
||||
_signature.reset(field);
|
||||
} else {
|
||||
_fields[field].uncast(value);
|
||||
_signature.set(field);
|
||||
}
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
template <class T> T get(Field field, T defaultValue) const {
|
||||
auto found = _fields.find(field);
|
||||
if (found != _fields.end()) {
|
||||
return (*found).second.cast<T>();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
FieldMap _fields;
|
||||
Signature _signature{0};
|
||||
Stamp _stamp{0};
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
mutable GPUObject* _gpuObject = nullptr;
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
friend class Backend;
|
||||
};
|
||||
|
||||
|
||||
typedef std::shared_ptr< State > StatePointer;
|
||||
uint32 getColorWriteMask() const { return get<uint32>(COLOR_WRITE_MASK, DEFAULT.colorWriteMask); }
|
||||
*/
|
||||
// The state values are stored in a Map called FieldMap
|
||||
// only the fields with non default value are saved
|
||||
|
||||
// All the possible fields
|
||||
enum Field {
|
||||
FILL_MODE,
|
||||
CULL_MODE,
|
||||
FRONT_FACE_CLOCKWISE,
|
||||
DEPTH_CLIP_ENABLE,
|
||||
SCISSOR_ENABLE,
|
||||
MULTISAMPLE_ENABLE,
|
||||
ANTIALISED_LINE_ENABLE,
|
||||
|
||||
DEPTH_BIAS,
|
||||
DEPTH_BIAS_SLOPE_SCALE,
|
||||
|
||||
DEPTH_TEST,
|
||||
|
||||
STENCIL_ACTIVATION,
|
||||
STENCIL_TEST_FRONT,
|
||||
STENCIL_TEST_BACK,
|
||||
|
||||
SAMPLE_MASK,
|
||||
ALPHA_TO_COVERAGE_ENABLE,
|
||||
|
||||
BLEND_FUNCTION,
|
||||
|
||||
COLOR_WRITE_MASK,
|
||||
|
||||
NUM_FIELDS, // not a valid field, just the count
|
||||
};
|
||||
|
||||
// the value of a field
|
||||
class Value {
|
||||
public:
|
||||
union {
|
||||
uint32 _unsigned_integer = 0;
|
||||
int32 _integer;
|
||||
float _float;
|
||||
};
|
||||
|
||||
template <typename T> void uncast(T v) { _integer = v; }
|
||||
|
||||
template <typename T> T cast() const { return T(_integer); }
|
||||
};
|
||||
|
||||
// The field map type
|
||||
typedef std::unordered_map<int32, Value> FieldMap;
|
||||
|
||||
const FieldMap& getFields() const { return _fields; }
|
||||
|
||||
// The signature of the state tells which fields of the state are not default
|
||||
// this way during rendering the Backend can compare it's current state and try to minimize the job to do
|
||||
typedef std::bitset<NUM_FIELDS> Signature;
|
||||
|
||||
Signature getSignature() const { return _signature; }
|
||||
|
||||
static Signature evalSignature(const Cache& state);
|
||||
|
||||
protected:
|
||||
State(const State& state);
|
||||
State& operator=(const State& state);
|
||||
|
||||
template <typename T> void set(Field field, T defaultValue, T value, T& dest) {
|
||||
dest = value;
|
||||
if (value == defaultValue) {
|
||||
//_fields.erase(field);
|
||||
_signature.reset(field);
|
||||
} else {
|
||||
//_fields[field].uncast(value);
|
||||
_signature.set(field);
|
||||
}
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
template <typename T> void set(Field field, T defaultValue, T value) {
|
||||
if (value == defaultValue) {
|
||||
_fields.erase(field);
|
||||
_signature.reset(field);
|
||||
} else {
|
||||
_fields[field].uncast(value);
|
||||
_signature.set(field);
|
||||
}
|
||||
_stamp++;
|
||||
}
|
||||
|
||||
template <typename T> T get(Field field, T defaultValue) const {
|
||||
auto found = _fields.find(field);
|
||||
if (found != _fields.end()) {
|
||||
return (*found).second.cast<T>();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
FieldMap _fields;
|
||||
Cache _values;
|
||||
Signature _signature{0};
|
||||
Stamp _stamp{0};
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
mutable GPUObject* _gpuObject = nullptr;
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
friend class Backend;
|
||||
};
|
||||
|
||||
template <> void State::Value::uncast<int>(int v) { _integer = v; }
|
||||
template <> void State::Value::uncast<float>(float v) { _float = v; }
|
||||
template <> void State::Value::uncast<unsigned int>(unsigned int v) { _unsigned_integer = v; }
|
||||
template <> void State::Value::uncast<State::DepthTest>(State::DepthTest v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<State::StencilActivation>(State::StencilActivation v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<State::StencilTest>(State::StencilTest v) { _integer = v.getRaw(); }
|
||||
template <> void State::Value::uncast<State::BlendFunction>(State::BlendFunction v) { _integer = v.getRaw(); }
|
||||
|
||||
template <> int State::Value::cast<int>() const { return _integer; }
|
||||
template <> float State::Value::cast<float>() const { return _float; }
|
||||
template <> unsigned int State::Value::cast<unsigned int>() const { return _unsigned_integer; }
|
||||
template <> State::DepthTest State::Value::cast<State::DepthTest>() const { return DepthTest(_integer); }
|
||||
template <> State::StencilActivation State::Value::cast<State::StencilActivation>() const { return StencilActivation(_integer); }
|
||||
template <> State::StencilTest State::Value::cast<State::StencilTest>() const { return StencilTest(_integer); }
|
||||
template <> State::BlendFunction State::Value::cast<State::BlendFunction>() const { return BlendFunction(_integer); }
|
||||
|
||||
typedef std::shared_ptr< State > StatePointer;
|
||||
typedef std::vector< StatePointer > States;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -97,7 +97,7 @@ Model::~Model() {
|
|||
Model::RenderPipelineLib Model::_renderPipelineLib;
|
||||
const GLint MATERIAL_GPU_SLOT = 3;
|
||||
|
||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey& key,
|
||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
gpu::ShaderPointer& pixelShader ) {
|
||||
|
||||
|
@ -133,12 +133,8 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey& key,
|
|||
state->setBlendFunction(key.isTranslucent(),
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
auto it = insert(value_type(key.getRaw(),
|
||||
RenderPipeline(
|
||||
gpu::PipelinePointer( gpu::Pipeline::create(program, state) ),
|
||||
std::shared_ptr<Locations>(locations)
|
||||
)));
|
||||
auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
auto it = insert(value_type(key.getRaw(), RenderPipeline(pipeline, std::shared_ptr<Locations>(locations))));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -505,7 +505,7 @@ private:
|
|||
public:
|
||||
gpu::PipelinePointer _pipeline;
|
||||
std::shared_ptr<Locations> _locations;
|
||||
RenderPipeline(gpu::PipelinePointer& pipeline, std::shared_ptr<Locations>& locations) :
|
||||
RenderPipeline(gpu::PipelinePointer pipeline, std::shared_ptr<Locations> locations) :
|
||||
_pipeline(pipeline), _locations(locations) {}
|
||||
};
|
||||
|
||||
|
@ -515,7 +515,7 @@ private:
|
|||
typedef RenderKey Key;
|
||||
|
||||
|
||||
void addRenderPipeline(Key& key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
||||
void addRenderPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
||||
|
||||
void initLocations(gpu::ShaderPointer& program, Locations& locations);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue