mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
Adding the State to gpu and wiring the pipeline in glBackend to potentially make it work soon :)
This commit is contained in:
parent
69667fb5ca
commit
19a96c4815
12 changed files with 578 additions and 94 deletions
|
@ -82,6 +82,15 @@ public:
|
||||||
return reinterpret_cast<T*>(pipeline.getGPUObject());
|
return reinterpret_cast<T*>(pipeline.getGPUObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
static void setGPUObject(const State& state, T* so) {
|
||||||
|
state.setGPUObject(so);
|
||||||
|
}
|
||||||
|
template< typename T >
|
||||||
|
static T* getGPUObject(const State& state) {
|
||||||
|
return reinterpret_cast<T*>(state.getGPUObject());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
|
class GPUObject;
|
||||||
|
|
||||||
|
typedef int Stamp;
|
||||||
|
|
||||||
typedef unsigned int uint32;
|
typedef unsigned int uint32;
|
||||||
typedef int int32;
|
typedef int int32;
|
||||||
typedef unsigned short uint16;
|
typedef unsigned short uint16;
|
||||||
|
|
|
@ -79,18 +79,61 @@ public:
|
||||||
public:
|
public:
|
||||||
class Command {
|
class Command {
|
||||||
public:
|
public:
|
||||||
typedef void *GlFunction(GLenum);
|
|
||||||
|
|
||||||
GlFunction _glFunction;
|
|
||||||
GLenum _enum;
|
|
||||||
|
|
||||||
void run() { _glFunction(_enum); }
|
virtual void run() = 0;
|
||||||
|
|
||||||
|
Command() {}
|
||||||
|
virtual ~Command() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< Command > Commands;
|
template <class T> class Command1 : public Command {
|
||||||
|
public:
|
||||||
|
typedef void (*GLFunction)(typename T);
|
||||||
|
|
||||||
|
void run() { (_func)(_param); }
|
||||||
|
|
||||||
|
Command1(GLFunction func, T param) : _func(func), _param(param) {};
|
||||||
|
|
||||||
|
GLFunction _func;
|
||||||
|
T _param;
|
||||||
|
};
|
||||||
|
template <class T, class U> class Command2 : public Command {
|
||||||
|
public:
|
||||||
|
typedef void (*GLFunction)(typename T, typename U);
|
||||||
|
|
||||||
|
void run() { (_func)(_param0, _param1); }
|
||||||
|
|
||||||
|
Command2(GLFunction func, T param0, U param1) : _func(func), _param0(param0), _param1(param1) {};
|
||||||
|
|
||||||
|
GLFunction _func;
|
||||||
|
T _param0;
|
||||||
|
U _param1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class V, class W> class Command4 : public Command {
|
||||||
|
public:
|
||||||
|
typedef void (*GLFunction)(typename T, typename U, typename V, typename W);
|
||||||
|
|
||||||
|
void run() { (_func)(_param0, _param1, _param2, _param3); }
|
||||||
|
|
||||||
|
Command4(GLFunction func, T param0, U param1, V param2, W param3) :
|
||||||
|
_func(func),
|
||||||
|
_param0(param0),
|
||||||
|
_param1(param1),
|
||||||
|
_param2(param2),
|
||||||
|
_param3(param3) {};
|
||||||
|
|
||||||
|
GLFunction _func;
|
||||||
|
T _param0;
|
||||||
|
U _param1;
|
||||||
|
V _param2;
|
||||||
|
W _param3;
|
||||||
|
};
|
||||||
|
typedef std::shared_ptr< Command > CommandPointer;
|
||||||
|
typedef std::vector< CommandPointer > Commands;
|
||||||
|
|
||||||
Commands _commands;
|
Commands _commands;
|
||||||
|
Stamp _stamp;
|
||||||
|
|
||||||
GLState();
|
GLState();
|
||||||
~GLState();
|
~GLState();
|
||||||
|
@ -100,6 +143,7 @@ public:
|
||||||
class GLPipeline : public GPUObject {
|
class GLPipeline : public GPUObject {
|
||||||
public:
|
public:
|
||||||
GLShader* _program;
|
GLShader* _program;
|
||||||
|
GLState* _state;
|
||||||
|
|
||||||
GLPipeline();
|
GLPipeline();
|
||||||
~GLPipeline();
|
~GLPipeline();
|
||||||
|
@ -203,14 +247,19 @@ protected:
|
||||||
GLuint _program;
|
GLuint _program;
|
||||||
bool _invalidProgram;
|
bool _invalidProgram;
|
||||||
|
|
||||||
|
State _state;
|
||||||
|
GLState::Commands _stateCommands;
|
||||||
|
bool _invalidState;
|
||||||
|
|
||||||
PipelineStageState() :
|
PipelineStageState() :
|
||||||
_pipeline(),
|
_pipeline(),
|
||||||
_program(0),
|
_program(0),
|
||||||
_invalidProgram(false)
|
_invalidProgram(false),
|
||||||
|
_state(),
|
||||||
|
_invalidState(false)
|
||||||
{}
|
{}
|
||||||
} _pipeline;
|
} _pipeline;
|
||||||
|
|
||||||
|
|
||||||
// TODO: As long as we have gl calls explicitely issued from interface
|
// 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
|
// 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
|
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
GLBackend::GLPipeline::GLPipeline() :
|
GLBackend::GLPipeline::GLPipeline() :
|
||||||
_program(nullptr)
|
_program(nullptr),
|
||||||
|
_state(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GLBackend::GLPipeline::~GLPipeline() {
|
GLBackend::GLPipeline::~GLPipeline() {
|
||||||
_program = nullptr;
|
_program = nullptr;
|
||||||
|
_state = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLPipeline* GLBackend::syncGPUObject(const Pipeline& pipeline) {
|
GLBackend::GLPipeline* GLBackend::syncGPUObject(const Pipeline& pipeline) {
|
||||||
|
@ -30,7 +32,29 @@ GLBackend::GLPipeline* GLBackend::syncGPUObject(const Pipeline& pipeline) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
// No object allocated yet, let's see if it's worth it...
|
||||||
|
ShaderPointer shader = pipeline.getProgram();
|
||||||
|
GLShader* programObject = GLBackend::syncGPUObject((*shader));
|
||||||
|
if (programObject == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatePointer state = pipeline.getState();
|
||||||
|
GLState* stateObject = GLBackend::syncGPUObject((*state));
|
||||||
|
if (stateObject == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Program and state are valid, we can create the pipeline object
|
||||||
|
if (!object) {
|
||||||
|
object = new GLPipeline();
|
||||||
|
Backend::setGPUObject(pipeline, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
object->_program = programObject;
|
||||||
|
object->_state = stateObject;
|
||||||
|
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
||||||
|
@ -46,8 +70,15 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline._pipeline = pipeline;
|
_pipeline._pipeline = pipeline;
|
||||||
_pipeline._program = pipelineObject->_program->_program;
|
|
||||||
_pipeline._invalidProgram = true;
|
if (_pipeline._program != pipelineObject->_program->_program) {
|
||||||
|
_pipeline._program = pipelineObject->_program->_program;
|
||||||
|
_pipeline._invalidProgram = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pipeline._stateCommands = pipelineObject->_state->_commands;
|
||||||
|
_pipeline._invalidState = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
||||||
|
@ -86,8 +117,15 @@ void GLBackend::updatePipeline() {
|
||||||
if (_pipeline._invalidProgram) {
|
if (_pipeline._invalidProgram) {
|
||||||
glUseProgram(_pipeline._program);
|
glUseProgram(_pipeline._program);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
|
_pipeline._invalidProgram = false;
|
||||||
|
}
|
||||||
|
|
||||||
_pipeline._invalidProgram = true;
|
if (_pipeline._invalidState) {
|
||||||
|
for (auto command: _pipeline._stateCommands) {
|
||||||
|
command->run();
|
||||||
|
}
|
||||||
|
CHECK_GL_ERROR();
|
||||||
|
_pipeline._invalidState = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
356
libraries/gpu/src/gpu/GLBackendState.cpp
Normal file
356
libraries/gpu/src/gpu/GLBackendState.cpp
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
//
|
||||||
|
// GLBackendState.cpp
|
||||||
|
// libraries/gpu/src/gpu
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 3/22/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
|
||||||
|
//
|
||||||
|
#include "GLBackendShared.h"
|
||||||
|
|
||||||
|
#include "Format.h"
|
||||||
|
|
||||||
|
using namespace gpu;
|
||||||
|
|
||||||
|
GLBackend::GLState::GLState()
|
||||||
|
{}
|
||||||
|
|
||||||
|
GLBackend::GLState::~GLState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef GLBackend::GLState::Command Command;
|
||||||
|
typedef GLBackend::GLState::CommandPointer CommandPointer;
|
||||||
|
typedef GLBackend::GLState::Command1<GLenum> Command1E;
|
||||||
|
typedef GLBackend::GLState::Command2<GLenum, GLenum> Command2E;
|
||||||
|
typedef GLBackend::GLState::Command2<GLfloat, GLfloat> Command2F;
|
||||||
|
typedef GLBackend::GLState::Command4<GLenum, GLenum, GLenum, GLenum> Command4E;
|
||||||
|
typedef GLBackend::GLState::Command4<GLfloat, GLfloat, GLfloat, GLfloat> Command4F;
|
||||||
|
typedef GLBackend::GLState::Command4<GLboolean, GLboolean, GLboolean, GLboolean> Command4B;
|
||||||
|
|
||||||
|
static GLenum GL_COMPARISON_FUNCTIONS[] = {
|
||||||
|
GL_NEVER,
|
||||||
|
GL_LESS,
|
||||||
|
GL_EQUAL,
|
||||||
|
GL_LEQUAL,
|
||||||
|
GL_GREATER,
|
||||||
|
GL_NOTEQUAL,
|
||||||
|
GL_GEQUAL,
|
||||||
|
GL_ALWAYS };
|
||||||
|
|
||||||
|
void glBackend_glPolygonMode(GLenum fillMode) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, fillMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateFillMode(GLBackend::GLState::Commands& commands, State::FillMode fillMode) {
|
||||||
|
static GLenum GL_FILL_MODES[] = { GL_POINT, GL_LINE, GL_FILL };
|
||||||
|
commands.push_back(CommandPointer(new Command1E(glBackend_glPolygonMode, GL_FILL_MODES[fillMode])));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateCullMode(GLBackend::GLState::Commands& commands, State::CullMode cullMode) {
|
||||||
|
static GLenum CULL_MODES[] = { GL_FRONT_AND_BACK, GL_FRONT, GL_BACK };
|
||||||
|
if (cullMode == State::CULL_NONE) {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, GLenum(GL_CULL_FACE))));
|
||||||
|
} else {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, GLenum(GL_CULL_FACE))));
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glCullFace, CULL_MODES[cullMode])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateDepthBias(GLBackend::GLState::Commands& commands, const State& state) {
|
||||||
|
if ((state.getDepthBias() == 0) && (state.getDepthBiasSlopeScale() == 0.0f)) {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, GLenum(GL_POLYGON_OFFSET_FILL))));
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, GLenum(GL_POLYGON_OFFSET_LINE))));
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, GLenum(GL_POLYGON_OFFSET_POINT))));
|
||||||
|
} else {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, GLenum(GL_POLYGON_OFFSET_FILL))));
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, GLenum(GL_POLYGON_OFFSET_LINE))));
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, GLenum(GL_POLYGON_OFFSET_POINT))));
|
||||||
|
commands.push_back(CommandPointer(new Command2F((Command2F::GLFunction)glPolygonOffset,
|
||||||
|
state.getDepthBiasSlopeScale(),
|
||||||
|
state.getDepthBias())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateFrontClockwise(GLBackend::GLState::Commands& commands, bool frontClockwise) {
|
||||||
|
static GLenum GL_FRONT_FACES[] = { GL_CCW, GL_CW };
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glFrontFace, GL_FRONT_FACES[frontClockwise])));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADD_ENABLE_DISABLE_COMMAND( NAME ) if (enable) {\
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, NAME)));\
|
||||||
|
} else {\
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, NAME)));\
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateDepthClipEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_DEPTH_CLAMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateScissorEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateMultisampleEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_MULTISAMPLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateAntialiasedLineEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_POINT_SMOOTH);
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_LINE_SMOOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateDepthEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateDepthWriteMask(GLBackend::GLState::Commands& commands, bool write) {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDepthMask, write)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateDepthFunc(GLBackend::GLState::Commands& commands, State::ComparisonFunction function) {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDepthFunc, GL_COMPARISON_FUNCTIONS[function])));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateStencilEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateStencilWriteMask(GLBackend::GLState::Commands& commands, uint32 mask) {
|
||||||
|
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glStencilMask, mask)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateStencilState(GLBackend::GLState::Commands& commands, const State& state) {
|
||||||
|
auto frontTest(state.getStencilTestFront());
|
||||||
|
auto backTest(state.getStencilTestBack());
|
||||||
|
|
||||||
|
commands.push_back(CommandPointer(new Command4E((Command4E::GLFunction)glBlendEquationSeparate,
|
||||||
|
GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest._function], state.getStencilReference(), state.getStencilReadMask())));
|
||||||
|
commands.push_back(CommandPointer(new Command4E((Command4E::GLFunction)glBlendEquationSeparate,
|
||||||
|
GL_BACK, GL_COMPARISON_FUNCTIONS[backTest._function], state.getStencilReference(), state.getStencilReadMask())));
|
||||||
|
|
||||||
|
static GLenum STENCIL_OPS[] = {
|
||||||
|
GL_KEEP,
|
||||||
|
GL_ZERO,
|
||||||
|
GL_REPLACE,
|
||||||
|
GL_INCR_WRAP,
|
||||||
|
GL_DECR_WRAP,
|
||||||
|
GL_INVERT,
|
||||||
|
GL_INCR,
|
||||||
|
GL_DECR };
|
||||||
|
|
||||||
|
commands.push_back(CommandPointer(new Command4E((Command4E::GLFunction)glStencilOpSeparate,
|
||||||
|
GL_FRONT, STENCIL_OPS[frontTest._failOp], STENCIL_OPS[frontTest._passOp], STENCIL_OPS[frontTest._depthFailOp])));
|
||||||
|
commands.push_back(CommandPointer(new Command4E((Command4E::GLFunction)glStencilOpSeparate,
|
||||||
|
GL_BACK, STENCIL_OPS[backTest._failOp], STENCIL_OPS[backTest._passOp], STENCIL_OPS[backTest._depthFailOp])));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateAlphaToCoverageEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateBlendEnable(GLBackend::GLState::Commands& commands, bool enable) {
|
||||||
|
ADD_ENABLE_DISABLE_COMMAND(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateBlendFunction(GLBackend::GLState::Commands& commands, const State& state) {
|
||||||
|
static GLenum GL_BLEND_OPS[] = {
|
||||||
|
GL_FUNC_ADD,
|
||||||
|
GL_FUNC_SUBTRACT,
|
||||||
|
GL_FUNC_REVERSE_SUBTRACT,
|
||||||
|
GL_MIN,
|
||||||
|
GL_MAX };
|
||||||
|
|
||||||
|
auto colorFunction = state.getBlendFunctionColor();
|
||||||
|
auto alphaFunction = state.getBlendFunctionColor();
|
||||||
|
|
||||||
|
commands.push_back(CommandPointer(new Command2E((Command2E::GLFunction)glBlendEquationSeparate,
|
||||||
|
GL_BLEND_OPS[colorFunction._operation],
|
||||||
|
GL_BLEND_OPS[alphaFunction._operation])));
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.push_back(CommandPointer(new Command4E((Command4E::GLFunction)glBlendFuncSeparate,
|
||||||
|
BLEND_ARGS[colorFunction._source],
|
||||||
|
BLEND_ARGS[colorFunction._destination],
|
||||||
|
BLEND_ARGS[alphaFunction._source],
|
||||||
|
BLEND_ARGS[alphaFunction._destination])));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateBlendFactor(GLBackend::GLState::Commands& commands, const Vec4& factor) {
|
||||||
|
commands.push_back(CommandPointer(new Command4F((Command4F::GLFunction)glBlendColor,
|
||||||
|
factor.x, factor.y, factor.z, factor.w)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateColorWriteMask(GLBackend::GLState::Commands& commands, State::ColorMask mask) {
|
||||||
|
commands.push_back(CommandPointer(new Command4B((Command4B::GLFunction)glColorMask,
|
||||||
|
mask & State::ColorMask::WRITE_RED,
|
||||||
|
mask & State::ColorMask::WRITE_GREEN,
|
||||||
|
mask & State::ColorMask::WRITE_BLUE,
|
||||||
|
mask & State::ColorMask::WRITE_ALPHA )));
|
||||||
|
}
|
||||||
|
|
||||||
|
GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
|
||||||
|
GLState* object = Backend::getGPUObject<GLBackend::GLState>(state);
|
||||||
|
|
||||||
|
// If GPU object already created then good
|
||||||
|
if (object) {
|
||||||
|
if (object->_stamp == state.getStamp()) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else allocate and create the GLState
|
||||||
|
if (!object) {
|
||||||
|
object = new GLState();
|
||||||
|
Backend::setGPUObject(state, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
// here, we need to regenerate something so let's do it all
|
||||||
|
object->_commands.clear();
|
||||||
|
object->_stamp = state.getStamp();
|
||||||
|
|
||||||
|
bool depthBias = false;
|
||||||
|
|
||||||
|
bool depthEnabled = false;
|
||||||
|
bool depthState = false;
|
||||||
|
|
||||||
|
bool stencilEnabled = false;
|
||||||
|
bool stencilState = false;
|
||||||
|
|
||||||
|
bool blendEnabled = false;
|
||||||
|
bool blendFunction = false;
|
||||||
|
bool blendFactor = false;
|
||||||
|
|
||||||
|
// go thorugh the list of state fields in the State and record the corresponding gl command
|
||||||
|
for (auto field: state.getFields()) {
|
||||||
|
switch(field.first) {
|
||||||
|
case State::FILL_MODE: {
|
||||||
|
generateFillMode(object->_commands, State::FillMode(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::CULL_MODE: {
|
||||||
|
generateCullMode(object->_commands, State::CullMode(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::DEPTH_BIAS:
|
||||||
|
case State::DEPTH_BIAS_SLOPE_SCALE: {
|
||||||
|
depthBias = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::FRONT_CLOCKWISE: {
|
||||||
|
generateFrontClockwise(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::DEPTH_CLIP_ENABLE: {
|
||||||
|
generateDepthClipEnable(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::SCISSOR_ENABLE: {
|
||||||
|
generateScissorEnable(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::MULTISAMPLE_ENABLE: {
|
||||||
|
generateMultisampleEnable(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::ANTIALISED_LINE_ENABLE: {
|
||||||
|
generateAntialiasedLineEnable(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::DEPTH_ENABLE: {
|
||||||
|
depthEnabled = bool(field.second._integer);
|
||||||
|
generateDepthEnable(object->_commands, depthEnabled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::DEPTH_WRITE_MASK:
|
||||||
|
case State::DEPTH_FUNC: {
|
||||||
|
depthState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::STENCIL_ENABLE: {
|
||||||
|
stencilEnabled = bool(field.second._integer);
|
||||||
|
generateStencilEnable(object->_commands, stencilEnabled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::STENCIL_WRITE_MASK:
|
||||||
|
case State::STENCIL_READ_MASK:
|
||||||
|
case State::STENCIL_REFERENCE:
|
||||||
|
case State::STENCIL_TEST_FRONT:
|
||||||
|
case State::STENCIL_TEST_BACK: {
|
||||||
|
stencilState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::SAMPLE_MASK: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::ALPHA_TO_COVERAGE_ENABLE: {
|
||||||
|
generateAlphaToCoverageEnable(object->_commands, bool(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::BLEND_ENABLE: {
|
||||||
|
blendEnabled = field.second._integer;
|
||||||
|
generateBlendEnable(object->_commands, blendEnabled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::BLEND_FUNCTION_COLOR:
|
||||||
|
case State::BLEND_FUNCTION_ALPHA: {
|
||||||
|
blendFunction = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::BLEND_FACTOR_X:
|
||||||
|
case State::BLEND_FACTOR_Y:
|
||||||
|
case State::BLEND_FACTOR_Z:
|
||||||
|
case State::BLEND_FACTOR_W: {
|
||||||
|
blendFactor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case State::COLOR_WRITE_MASK: {
|
||||||
|
generateColorWriteMask(object->_commands, State::ColorMask(field.second._integer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthBias) {
|
||||||
|
generateDepthBias(object->_commands, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthEnabled) {
|
||||||
|
generateDepthWriteMask(object->_commands, state.getDepthWriteMask());
|
||||||
|
generateDepthFunc(object->_commands, state.getDepthFunc());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stencilEnabled) {
|
||||||
|
generateStencilState(object->_commands, state);
|
||||||
|
generateStencilWriteMask(object->_commands, state.getStencilWriteMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blendEnabled) {
|
||||||
|
generateBlendFunction(object->_commands, state);
|
||||||
|
generateBlendFactor(object->_commands, state.getBlendFactor());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ using namespace gpu;
|
||||||
|
|
||||||
Pipeline::Pipeline():
|
Pipeline::Pipeline():
|
||||||
_program(),
|
_program(),
|
||||||
_states()
|
_state()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ Pipeline::~Pipeline()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline* Pipeline::create(const ShaderPointer& program, const States& states) {
|
Pipeline* Pipeline::create(const ShaderPointer& program, const StatePointer& state) {
|
||||||
Pipeline* pipeline = new Pipeline();
|
Pipeline* pipeline = new Pipeline();
|
||||||
pipeline->_program = program;
|
pipeline->_program = program;
|
||||||
pipeline->_states = states;
|
pipeline->_state = state;
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,16 +22,16 @@ namespace gpu {
|
||||||
|
|
||||||
class Pipeline {
|
class Pipeline {
|
||||||
public:
|
public:
|
||||||
static Pipeline* create(const ShaderPointer& program, const States& states);
|
static Pipeline* create(const ShaderPointer& program, const StatePointer& state);
|
||||||
~Pipeline();
|
~Pipeline();
|
||||||
|
|
||||||
const ShaderPointer& getProgram() const { return _program; }
|
const ShaderPointer& getProgram() const { return _program; }
|
||||||
|
|
||||||
const States& getStates() const { return _states; }
|
const StatePointer& getState() const { return _state; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ShaderPointer _program;
|
ShaderPointer _program;
|
||||||
States _states;
|
StatePointer _state;
|
||||||
|
|
||||||
Pipeline();
|
Pipeline();
|
||||||
Pipeline(const Pipeline& pipeline); // deep copy of the sysmem shader
|
Pipeline(const Pipeline& pipeline); // deep copy of the sysmem shader
|
||||||
|
|
|
@ -24,10 +24,6 @@
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
class GPUObject;
|
|
||||||
|
|
||||||
typedef int Stamp;
|
|
||||||
|
|
||||||
class Resource {
|
class Resource {
|
||||||
public:
|
public:
|
||||||
typedef unsigned char Byte;
|
typedef unsigned char Byte;
|
||||||
|
|
|
@ -22,21 +22,25 @@ State::~State()
|
||||||
void State::set(Field field, bool value) {
|
void State::set(Field field, bool value) {
|
||||||
auto found = _fields.at(field);
|
auto found = _fields.at(field);
|
||||||
found._integer = value;
|
found._integer = value;
|
||||||
|
_stamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::set(Field field, uint32 value) {
|
void State::set(Field field, uint32 value) {
|
||||||
auto found = _fields.at(field);
|
auto found = _fields.at(field);
|
||||||
found._unsigned_integer = value;
|
found._unsigned_integer = value;
|
||||||
|
_stamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::set(Field field, int32 value) {
|
void State::set(Field field, int32 value) {
|
||||||
auto found = _fields.at(field);
|
auto found = _fields.at(field);
|
||||||
found._integer = value;
|
found._integer = value;
|
||||||
|
_stamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::set(Field field, float value) {
|
void State::set(Field field, float value) {
|
||||||
auto found = _fields.at(field);
|
auto found = _fields.at(field);
|
||||||
found._float = value;
|
found._float = value;
|
||||||
|
_stamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
State::Value State::get(Field field) const {
|
State::Value State::get(Field field) const {
|
||||||
|
|
|
@ -26,12 +26,14 @@ public:
|
||||||
State() {}
|
State() {}
|
||||||
virtual ~State();
|
virtual ~State();
|
||||||
|
|
||||||
|
const Stamp getStamp() const { return _stamp; }
|
||||||
|
|
||||||
// All the possible fields
|
// All the possible fields
|
||||||
enum Field {
|
enum Field {
|
||||||
FILL_MODE,
|
FILL_MODE,
|
||||||
CULL_MODE,
|
CULL_MODE,
|
||||||
|
|
||||||
DEPTH_BIAS,
|
DEPTH_BIAS,
|
||||||
DEPTH_BIAS_CLAMP,
|
|
||||||
DEPTH_BIAS_SLOPE_SCALE,
|
DEPTH_BIAS_SLOPE_SCALE,
|
||||||
|
|
||||||
FRONT_CLOCKWISE,
|
FRONT_CLOCKWISE,
|
||||||
|
@ -47,37 +49,22 @@ public:
|
||||||
STENCIL_ENABLE,
|
STENCIL_ENABLE,
|
||||||
STENCIL_READ_MASK,
|
STENCIL_READ_MASK,
|
||||||
STENCIL_WRITE_MASK,
|
STENCIL_WRITE_MASK,
|
||||||
|
STENCIL_TEST_FRONT,
|
||||||
STENCIL_FUNC_FRONT,
|
STENCIL_TEST_BACK,
|
||||||
STENCIL_FRONT_FUNC,
|
|
||||||
STENCIL_FRONT_FAIL_OP,
|
|
||||||
STENCIL_FRONT_DEPTH_FAIL_OP,
|
|
||||||
STENCIL_FRONT_PASS_OP,
|
|
||||||
|
|
||||||
STENCIL_BACK_FUNC,
|
|
||||||
STENCIL_BACK_FAIL_OP,
|
|
||||||
STENCIL_BACK_DEPTH_FAIL_OP,
|
|
||||||
STENCIL_BACK_PASS_OP,
|
|
||||||
STENCIL_FUNC_BACK,
|
|
||||||
|
|
||||||
STENCIL_REFERENCE,
|
STENCIL_REFERENCE,
|
||||||
|
|
||||||
SAMPLE_MASK,
|
SAMPLE_MASK,
|
||||||
ALPHA_TO_COVERAGE_ENABLE,
|
ALPHA_TO_COVERAGE_ENABLE,
|
||||||
|
|
||||||
|
BLEND_ENABLE,
|
||||||
|
BLEND_FUNCTION_COLOR,
|
||||||
|
BLEND_FUNCTION_ALPHA,
|
||||||
BLEND_FACTOR_X,
|
BLEND_FACTOR_X,
|
||||||
BLEND_FACTOR_Y,
|
BLEND_FACTOR_Y,
|
||||||
BLEND_FACTOR_Z,
|
BLEND_FACTOR_Z,
|
||||||
BLEND_FACTOR_W,
|
BLEND_FACTOR_W,
|
||||||
|
|
||||||
BLEND_INDEPENDANT_ENABLE,
|
COLOR_WRITE_MASK,
|
||||||
BLEND_ENABLE,
|
|
||||||
BLEND_SOURCE,
|
|
||||||
BLEND_DESTINATION,
|
|
||||||
BLEND_OPERATION,
|
|
||||||
BLEND_SOURCE_ALPHA,
|
|
||||||
BLEND_DESTINATION_ALPHA,
|
|
||||||
BLEND_OPERATION_ALPHA,
|
|
||||||
BLEND_WRITE_MASK,
|
|
||||||
|
|
||||||
NUM_FIELDS, // not a valid field, just the count
|
NUM_FIELDS, // not a valid field, just the count
|
||||||
};
|
};
|
||||||
|
@ -138,10 +125,6 @@ public:
|
||||||
SRC_ALPHA_SAT,
|
SRC_ALPHA_SAT,
|
||||||
BLEND_FACTOR,
|
BLEND_FACTOR,
|
||||||
INV_BLEND_FACTOR,
|
INV_BLEND_FACTOR,
|
||||||
SRC1_COLOR,
|
|
||||||
INV_SRC1_COLOR,
|
|
||||||
SRC1_ALPHA,
|
|
||||||
INV_SRC1_ALPHA,
|
|
||||||
|
|
||||||
NUM_BLEND_ARGS,
|
NUM_BLEND_ARGS,
|
||||||
};
|
};
|
||||||
|
@ -166,6 +149,33 @@ public:
|
||||||
WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ),
|
WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StencilTest {
|
||||||
|
public:
|
||||||
|
int8 _failOp = STENCIL_OP_KEEP;
|
||||||
|
int8 _depthFailOp = STENCIL_OP_KEEP;
|
||||||
|
int8 _passOp = STENCIL_OP_KEEP;
|
||||||
|
int8 _function = ALWAYS;
|
||||||
|
|
||||||
|
StencilTest(StencilOp failOp, StencilOp depthFailOp, StencilOp passOp, ComparisonFunction func) :
|
||||||
|
_failOp(failOp), _depthFailOp(depthFailOp), _passOp(passOp), _function(func) {}
|
||||||
|
|
||||||
|
int32 raw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||||
|
StencilTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class BlendFunction {
|
||||||
|
public:
|
||||||
|
int8 _source = ONE;
|
||||||
|
int8 _operation = BLEND_OP_ADD;
|
||||||
|
int8 _destination = ZERO;
|
||||||
|
int8 _spare = 0;
|
||||||
|
|
||||||
|
BlendFunction(BlendArg source, BlendOp operation, BlendArg destination) :
|
||||||
|
_source(source), _operation(operation), _destination(destination) {}
|
||||||
|
|
||||||
|
int32 raw() const { return *(reinterpret_cast<const int32*>(this)); }
|
||||||
|
BlendFunction(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
|
||||||
|
};
|
||||||
|
|
||||||
class Value {
|
class Value {
|
||||||
public:
|
public:
|
||||||
|
@ -177,6 +187,8 @@ public:
|
||||||
};
|
};
|
||||||
typedef std::unordered_map<Field, Value> FieldMap;
|
typedef std::unordered_map<Field, Value> FieldMap;
|
||||||
|
|
||||||
|
const FieldMap& getFields() const { return _fields; }
|
||||||
|
|
||||||
void set(Field field, bool value);
|
void set(Field field, bool value);
|
||||||
void set(Field field, uint32 value);
|
void set(Field field, uint32 value);
|
||||||
void set(Field field, int32 value);
|
void set(Field field, int32 value);
|
||||||
|
@ -189,11 +201,9 @@ public:
|
||||||
FillMode getFillMode() const { return FillMode(get(FILL_MODE)._integer); }
|
FillMode getFillMode() const { return FillMode(get(FILL_MODE)._integer); }
|
||||||
CullMode getCullMode() const { return CullMode(get(CULL_MODE)._integer); }
|
CullMode getCullMode() const { return CullMode(get(CULL_MODE)._integer); }
|
||||||
|
|
||||||
void setDepthBias(int32 bias) { set(DEPTH_BIAS, bias); }
|
void setDepthBias(float bias) { set(DEPTH_BIAS, bias); }
|
||||||
void setDepthBiasClamp(float clamp) { set(DEPTH_BIAS_CLAMP, clamp); }
|
|
||||||
void setDepthBiasSlopeScale(float scale) { set(DEPTH_BIAS_SLOPE_SCALE, scale); }
|
void setDepthBiasSlopeScale(float scale) { set(DEPTH_BIAS_SLOPE_SCALE, scale); }
|
||||||
int32 getDepthBias() const { return get(DEPTH_BIAS)._integer; }
|
float getDepthBias() const { return get(DEPTH_BIAS)._integer; }
|
||||||
float getDepthBiasClamp() const { return get(DEPTH_BIAS_CLAMP)._float; }
|
|
||||||
float getDepthBiasSlopeScale() const { return get(DEPTH_BIAS_SLOPE_SCALE)._float; }
|
float getDepthBiasSlopeScale() const { return get(DEPTH_BIAS_SLOPE_SCALE)._float; }
|
||||||
|
|
||||||
void setFrontClockwise(bool enable) { set(FRONT_CLOCKWISE, enable); }
|
void setFrontClockwise(bool enable) { set(FRONT_CLOCKWISE, enable); }
|
||||||
|
@ -221,23 +231,10 @@ public:
|
||||||
uint8 getStencilReadMask() const { return get(STENCIL_READ_MASK)._unsigned_integer; }
|
uint8 getStencilReadMask() const { return get(STENCIL_READ_MASK)._unsigned_integer; }
|
||||||
uint8 getStencilWriteMask() const { return get(STENCIL_WRITE_MASK)._unsigned_integer; }
|
uint8 getStencilWriteMask() const { return get(STENCIL_WRITE_MASK)._unsigned_integer; }
|
||||||
|
|
||||||
void setStencilFrontFailOp(StencilOp op) { set(STENCIL_FRONT_FAIL_OP, op); }
|
void setStencilTestFront(StencilTest test) { set(STENCIL_TEST_FRONT, test.raw()); }
|
||||||
void setStencilFrontDepthFailOp(StencilOp op) { set(STENCIL_FRONT_DEPTH_FAIL_OP, op); }
|
void setStencilTestBack(StencilTest test) { set(STENCIL_TEST_BACK, test.raw()); }
|
||||||
void setStencilFrontPassOp(StencilOp op) { set(STENCIL_FRONT_PASS_OP, op); }
|
StencilTest getStencilTestFront() const { return StencilTest(get(STENCIL_TEST_FRONT)._integer); }
|
||||||
void setStencilFrontFunc(ComparisonFunction func) { set(STENCIL_FRONT_FUNC, func); }
|
StencilTest getStencilTestBack() const { return StencilTest(get(STENCIL_TEST_BACK)._integer); }
|
||||||
StencilOp getStencilFrontFailOp() const { return StencilOp(get(STENCIL_FRONT_FAIL_OP)._integer); }
|
|
||||||
StencilOp getStencilFrontDepthFailOp() const { return StencilOp(get(STENCIL_FRONT_DEPTH_FAIL_OP)._integer); }
|
|
||||||
StencilOp getStencilFrontPassOp() const { return StencilOp(get(STENCIL_FRONT_PASS_OP)._integer); }
|
|
||||||
ComparisonFunction getStencilFrontFunc() const { return ComparisonFunction(get(STENCIL_FRONT_FUNC)._integer); }
|
|
||||||
|
|
||||||
void setStencilBackFailOp(StencilOp op) { set(STENCIL_BACK_FAIL_OP, op); }
|
|
||||||
void setStencilBackDepthFailOp(StencilOp op) { set(STENCIL_BACK_DEPTH_FAIL_OP, op); }
|
|
||||||
void setStencilBackPassOp(StencilOp op) { set(STENCIL_BACK_PASS_OP, op); }
|
|
||||||
void setStencilBackFunc(ComparisonFunction func) { set(STENCIL_BACK_FUNC, func); }
|
|
||||||
StencilOp getStencilBackFailOp() const { return StencilOp(get(STENCIL_BACK_FAIL_OP)._integer); }
|
|
||||||
StencilOp getStencilBackDepthFailOp() const { return StencilOp(get(STENCIL_BACK_DEPTH_FAIL_OP)._integer); }
|
|
||||||
StencilOp getStencilBackPassOp() const { return StencilOp(get(STENCIL_BACK_PASS_OP)._integer); }
|
|
||||||
ComparisonFunction getStencilBackFunc() const { return ComparisonFunction(get(STENCIL_BACK_FUNC)._integer); }
|
|
||||||
|
|
||||||
void setStencilReference(uint32 ref) { set(STENCIL_REFERENCE, ref); }
|
void setStencilReference(uint32 ref) { set(STENCIL_REFERENCE, ref); }
|
||||||
uint32 getStencilReference() const { return get(STENCIL_REFERENCE)._unsigned_integer; }
|
uint32 getStencilReference() const { return get(STENCIL_REFERENCE)._unsigned_integer; }
|
||||||
|
@ -247,39 +244,30 @@ public:
|
||||||
|
|
||||||
void setSampleMask(uint32 mask) { set(SAMPLE_MASK, mask); }
|
void setSampleMask(uint32 mask) { set(SAMPLE_MASK, mask); }
|
||||||
uint32 getSampleMask() const { return get(SAMPLE_MASK)._unsigned_integer; }
|
uint32 getSampleMask() const { return get(SAMPLE_MASK)._unsigned_integer; }
|
||||||
|
|
||||||
// void setBlendIndependantEnable(bool enable) { set(BLEND_INDEPENDANT_ENABLE, enable); }
|
|
||||||
// bool getBlendIndependantEnable() const { return get(BLEND_INDEPENDANT_ENABLE)._integer; }
|
|
||||||
|
|
||||||
void setBlendEnable(bool enable) { set(BLEND_ENABLE, enable); }
|
void setBlendEnable(bool enable) { set(BLEND_ENABLE, enable); }
|
||||||
bool getBlendEnable() const { return get(BLEND_ENABLE)._integer; }
|
bool getBlendEnable() const { return get(BLEND_ENABLE)._integer; }
|
||||||
|
|
||||||
void setBlendSource(BlendArg source) { set(BLEND_SOURCE, source); }
|
void setBlendFunctionColor(BlendFunction function) { set(BLEND_FUNCTION_COLOR, function.raw()); }
|
||||||
void setBlendDestination(BlendArg destination) { set(BLEND_DESTINATION, destination); }
|
BlendFunction getBlendFunctionColor() const { return BlendFunction(get(BLEND_FUNCTION_COLOR)._integer); }
|
||||||
void setBlendOperation(BlendOp operation) { set(BLEND_OPERATION, operation); }
|
void setBlendFunctionAlpha(BlendFunction function) { set(BLEND_FUNCTION_ALPHA, function.raw()); }
|
||||||
BlendArg getBlendSource() const { return BlendArg(get(BLEND_SOURCE)._integer); }
|
BlendFunction getBlendFunctionAlpha() const { return BlendFunction(get(BLEND_FUNCTION_ALPHA)._integer); }
|
||||||
BlendArg getBlendDestination() const { return BlendArg(get(BLEND_DESTINATION)._integer); }
|
|
||||||
BlendOp getBlendOperation() const { return BlendOp(get(BLEND_OPERATION)._integer); }
|
|
||||||
|
|
||||||
void setBlendSourceAlpha(BlendArg source) { set(BLEND_SOURCE_ALPHA, source); }
|
|
||||||
void setBlendDestinationAlpha(BlendArg destination) { set(BLEND_DESTINATION_ALPHA, destination); }
|
|
||||||
void setBlendOperationAlpha(BlendOp operation) { set(BLEND_OPERATION_ALPHA, operation); }
|
|
||||||
BlendArg getBlendSourceAlpha() const { return BlendArg(get(BLEND_SOURCE_ALPHA)._integer); }
|
|
||||||
BlendArg getBlendDestinationAlpha() const { return BlendArg(get(BLEND_DESTINATION_ALPHA)._integer); }
|
|
||||||
BlendOp getBlendOperationAlpha() const { return BlendOp(get(BLEND_OPERATION_ALPHA)._integer); }
|
|
||||||
|
|
||||||
void setBlendWriteMask(ColorMask mask) { set(BLEND_WRITE_MASK, mask); }
|
|
||||||
ColorMask getBlendWriteMask() const { return ColorMask(get(BLEND_WRITE_MASK)._integer); }
|
|
||||||
|
|
||||||
void setBlendFactor(const Vec4& factor) { set(BLEND_FACTOR_X, factor.x); set(BLEND_FACTOR_Y, factor.y); set(BLEND_FACTOR_Z, factor.z); set(BLEND_FACTOR_W, factor.w); }
|
void setBlendFactor(const Vec4& factor) { set(BLEND_FACTOR_X, factor.x); set(BLEND_FACTOR_Y, factor.y); set(BLEND_FACTOR_Z, factor.z); set(BLEND_FACTOR_W, factor.w); }
|
||||||
Vec4 getBlendFactor() const { return Vec4(get(BLEND_FACTOR_X)._float, get(BLEND_FACTOR_Y)._float, get(BLEND_FACTOR_Z)._float, get(BLEND_FACTOR_W)._float); }
|
Vec4 getBlendFactor() const { return Vec4(get(BLEND_FACTOR_X)._float, get(BLEND_FACTOR_Y)._float, get(BLEND_FACTOR_Z)._float, get(BLEND_FACTOR_W)._float); }
|
||||||
|
|
||||||
|
|
||||||
|
void setColorWriteMask(ColorMask mask) { set(COLOR_WRITE_MASK, mask); }
|
||||||
|
ColorMask getColorWriteMask() const { return ColorMask(get(COLOR_WRITE_MASK)._integer); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
State(const State& state);
|
State(const State& state);
|
||||||
State& operator=(const State& state);
|
State& operator=(const State& state);
|
||||||
|
|
||||||
FieldMap _fields;
|
FieldMap _fields;
|
||||||
|
|
||||||
|
Stamp _stamp;
|
||||||
|
|
||||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||||
mutable GPUObject* _gpuObject = NULL;
|
mutable GPUObject* _gpuObject = NULL;
|
||||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||||
|
|
|
@ -215,7 +215,13 @@ SunSkyStage::SunSkyStage() :
|
||||||
auto skyFromAtmosphereVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(SkyFromAtmosphere_vert)));
|
auto skyFromAtmosphereVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(SkyFromAtmosphere_vert)));
|
||||||
auto skyFromAtmosphereFragment = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(SkyFromAtmosphere_frag)));
|
auto skyFromAtmosphereFragment = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(SkyFromAtmosphere_frag)));
|
||||||
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyFromAtmosphereVertex, skyFromAtmosphereFragment));
|
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyFromAtmosphereVertex, skyFromAtmosphereFragment));
|
||||||
_skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, gpu::States()));
|
|
||||||
|
auto skyState = gpu::StatePointer(new gpu::State());
|
||||||
|
skyState->setDepthEnable(false);
|
||||||
|
skyState->setStencilEnable(false);
|
||||||
|
skyState->setBlendEnable(false);
|
||||||
|
|
||||||
|
_skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,29 @@ private:
|
||||||
int _blendNumber;
|
int _blendNumber;
|
||||||
int _appliedBlendNumber;
|
int _appliedBlendNumber;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static gpu::PipelinePointer _program;
|
||||||
|
static gpu::PipelinePointer _normalMapProgram;
|
||||||
|
static gpu::PipelinePointer _specularMapProgram;
|
||||||
|
static gpu::PipelinePointer _normalSpecularMapProgram;
|
||||||
|
static gpu::PipelinePointer _translucentProgram;
|
||||||
|
|
||||||
|
static gpu::PipelinePointer _lightmapProgram;
|
||||||
|
static gpu::PipelinePointer _lightmapNormalMapProgram;
|
||||||
|
static gpu::PipelinePointer _lightmapSpecularMapProgram;
|
||||||
|
static gpu::PipelinePointer _lightmapNormalSpecularMapProgram;
|
||||||
|
|
||||||
|
static gpu::PipelinePointer _shadowProgram;
|
||||||
|
|
||||||
|
static gpu::PipelinePointer _skinProgram;
|
||||||
|
static gpu::PipelinePointer _skinNormalMapProgram;
|
||||||
|
static gpu::PipelinePointer _skinSpecularMapProgram;
|
||||||
|
static gpu::PipelinePointer _skinNormalSpecularMapProgram;
|
||||||
|
static gpu::PipelinePointer _skinTranslucentProgram;
|
||||||
|
|
||||||
|
static gpu::PipelinePointer _skinShadowProgram;
|
||||||
|
*/
|
||||||
|
|
||||||
static gpu::ShaderPointer _program;
|
static gpu::ShaderPointer _program;
|
||||||
static gpu::ShaderPointer _normalMapProgram;
|
static gpu::ShaderPointer _normalMapProgram;
|
||||||
static gpu::ShaderPointer _specularMapProgram;
|
static gpu::ShaderPointer _specularMapProgram;
|
||||||
|
@ -473,6 +496,17 @@ private:
|
||||||
|
|
||||||
static AbstractViewStateInterface* _viewState;
|
static AbstractViewStateInterface* _viewState;
|
||||||
|
|
||||||
|
/* class RenderKey {
|
||||||
|
public:
|
||||||
|
enum Flag {
|
||||||
|
TRANSLUCENT = 0,
|
||||||
|
HAS_LIGHTMAP,
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderMode mode;
|
||||||
|
|
||||||
|
};
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QPointer<Model>)
|
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||||
|
|
Loading…
Reference in a new issue