Adding the State to gpu and wiring the pipeline in glBackend to potentially make it work soon :)

This commit is contained in:
Sam Gateau 2015-03-23 22:33:25 -07:00
parent 69667fb5ca
commit 19a96c4815
12 changed files with 578 additions and 94 deletions

View file

@ -82,6 +82,15 @@ public:
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:
};

View file

@ -16,6 +16,10 @@
namespace gpu {
class GPUObject;
typedef int Stamp;
typedef unsigned int uint32;
typedef int int32;
typedef unsigned short uint16;

View file

@ -79,18 +79,61 @@ public:
public:
class Command {
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;
Stamp _stamp;
GLState();
~GLState();
@ -100,6 +143,7 @@ public:
class GLPipeline : public GPUObject {
public:
GLShader* _program;
GLState* _state;
GLPipeline();
~GLPipeline();
@ -203,14 +247,19 @@ protected:
GLuint _program;
bool _invalidProgram;
State _state;
GLState::Commands _stateCommands;
bool _invalidState;
PipelineStageState() :
_pipeline(),
_program(0),
_invalidProgram(false)
_invalidProgram(false),
_state(),
_invalidState(false)
{}
} _pipeline;
// 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

View file

@ -15,11 +15,13 @@
using namespace gpu;
GLBackend::GLPipeline::GLPipeline() :
_program(nullptr)
_program(nullptr),
_state(nullptr)
{}
GLBackend::GLPipeline::~GLPipeline() {
_program = nullptr;
_state = nullptr;
}
GLBackend::GLPipeline* GLBackend::syncGPUObject(const Pipeline& pipeline) {
@ -30,7 +32,29 @@ GLBackend::GLPipeline* GLBackend::syncGPUObject(const Pipeline& pipeline) {
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) {
@ -46,8 +70,15 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
}
_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) {
@ -86,8 +117,15 @@ void GLBackend::updatePipeline() {
if (_pipeline._invalidProgram) {
glUseProgram(_pipeline._program);
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;
}
}

View 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;
}

View file

@ -17,7 +17,7 @@ using namespace gpu;
Pipeline::Pipeline():
_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->_program = program;
pipeline->_states = states;
pipeline->_state = state;
return pipeline;
}

View file

@ -22,16 +22,16 @@ namespace gpu {
class Pipeline {
public:
static Pipeline* create(const ShaderPointer& program, const States& states);
static Pipeline* create(const ShaderPointer& program, const StatePointer& state);
~Pipeline();
const ShaderPointer& getProgram() const { return _program; }
const States& getStates() const { return _states; }
const StatePointer& getState() const { return _state; }
protected:
ShaderPointer _program;
States _states;
StatePointer _state;
Pipeline();
Pipeline(const Pipeline& pipeline); // deep copy of the sysmem shader

View file

@ -24,10 +24,6 @@
namespace gpu {
class GPUObject;
typedef int Stamp;
class Resource {
public:
typedef unsigned char Byte;

View file

@ -22,21 +22,25 @@ State::~State()
void State::set(Field field, bool value) {
auto found = _fields.at(field);
found._integer = value;
_stamp++;
}
void State::set(Field field, uint32 value) {
auto found = _fields.at(field);
found._unsigned_integer = value;
_stamp++;
}
void State::set(Field field, int32 value) {
auto found = _fields.at(field);
found._integer = value;
_stamp++;
}
void State::set(Field field, float value) {
auto found = _fields.at(field);
found._float = value;
_stamp++;
}
State::Value State::get(Field field) const {

View file

@ -26,12 +26,14 @@ public:
State() {}
virtual ~State();
const Stamp getStamp() const { return _stamp; }
// All the possible fields
enum Field {
FILL_MODE,
CULL_MODE,
DEPTH_BIAS,
DEPTH_BIAS_CLAMP,
DEPTH_BIAS_SLOPE_SCALE,
FRONT_CLOCKWISE,
@ -47,37 +49,22 @@ public:
STENCIL_ENABLE,
STENCIL_READ_MASK,
STENCIL_WRITE_MASK,
STENCIL_FUNC_FRONT,
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_TEST_FRONT,
STENCIL_TEST_BACK,
STENCIL_REFERENCE,
SAMPLE_MASK,
ALPHA_TO_COVERAGE_ENABLE,
BLEND_ENABLE,
BLEND_FUNCTION_COLOR,
BLEND_FUNCTION_ALPHA,
BLEND_FACTOR_X,
BLEND_FACTOR_Y,
BLEND_FACTOR_Z,
BLEND_FACTOR_W,
BLEND_INDEPENDANT_ENABLE,
BLEND_ENABLE,
BLEND_SOURCE,
BLEND_DESTINATION,
BLEND_OPERATION,
BLEND_SOURCE_ALPHA,
BLEND_DESTINATION_ALPHA,
BLEND_OPERATION_ALPHA,
BLEND_WRITE_MASK,
COLOR_WRITE_MASK,
NUM_FIELDS, // not a valid field, just the count
};
@ -138,10 +125,6 @@ public:
SRC_ALPHA_SAT,
BLEND_FACTOR,
INV_BLEND_FACTOR,
SRC1_COLOR,
INV_SRC1_COLOR,
SRC1_ALPHA,
INV_SRC1_ALPHA,
NUM_BLEND_ARGS,
};
@ -166,6 +149,33 @@ public:
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 {
public:
@ -177,6 +187,8 @@ public:
};
typedef std::unordered_map<Field, Value> FieldMap;
const FieldMap& getFields() const { return _fields; }
void set(Field field, bool value);
void set(Field field, uint32 value);
void set(Field field, int32 value);
@ -189,11 +201,9 @@ public:
FillMode getFillMode() const { return FillMode(get(FILL_MODE)._integer); }
CullMode getCullMode() const { return CullMode(get(CULL_MODE)._integer); }
void setDepthBias(int32 bias) { set(DEPTH_BIAS, bias); }
void setDepthBiasClamp(float clamp) { set(DEPTH_BIAS_CLAMP, clamp); }
void setDepthBias(float bias) { set(DEPTH_BIAS, bias); }
void setDepthBiasSlopeScale(float scale) { set(DEPTH_BIAS_SLOPE_SCALE, scale); }
int32 getDepthBias() const { return get(DEPTH_BIAS)._integer; }
float getDepthBiasClamp() const { return get(DEPTH_BIAS_CLAMP)._float; }
float getDepthBias() const { return get(DEPTH_BIAS)._integer; }
float getDepthBiasSlopeScale() const { return get(DEPTH_BIAS_SLOPE_SCALE)._float; }
void setFrontClockwise(bool enable) { set(FRONT_CLOCKWISE, enable); }
@ -221,23 +231,10 @@ public:
uint8 getStencilReadMask() const { return get(STENCIL_READ_MASK)._unsigned_integer; }
uint8 getStencilWriteMask() const { return get(STENCIL_WRITE_MASK)._unsigned_integer; }
void setStencilFrontFailOp(StencilOp op) { set(STENCIL_FRONT_FAIL_OP, op); }
void setStencilFrontDepthFailOp(StencilOp op) { set(STENCIL_FRONT_DEPTH_FAIL_OP, op); }
void setStencilFrontPassOp(StencilOp op) { set(STENCIL_FRONT_PASS_OP, op); }
void setStencilFrontFunc(ComparisonFunction func) { set(STENCIL_FRONT_FUNC, func); }
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 setStencilTestFront(StencilTest test) { set(STENCIL_TEST_FRONT, test.raw()); }
void setStencilTestBack(StencilTest test) { set(STENCIL_TEST_BACK, test.raw()); }
StencilTest getStencilTestFront() const { return StencilTest(get(STENCIL_TEST_FRONT)._integer); }
StencilTest getStencilTestBack() const { return StencilTest(get(STENCIL_TEST_BACK)._integer); }
void setStencilReference(uint32 ref) { set(STENCIL_REFERENCE, ref); }
uint32 getStencilReference() const { return get(STENCIL_REFERENCE)._unsigned_integer; }
@ -247,39 +244,30 @@ public:
void setSampleMask(uint32 mask) { set(SAMPLE_MASK, mask); }
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); }
bool getBlendEnable() const { return get(BLEND_ENABLE)._integer; }
void setBlendSource(BlendArg source) { set(BLEND_SOURCE, source); }
void setBlendDestination(BlendArg destination) { set(BLEND_DESTINATION, destination); }
void setBlendOperation(BlendOp operation) { set(BLEND_OPERATION, operation); }
BlendArg getBlendSource() const { return BlendArg(get(BLEND_SOURCE)._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 setBlendFunctionColor(BlendFunction function) { set(BLEND_FUNCTION_COLOR, function.raw()); }
BlendFunction getBlendFunctionColor() const { return BlendFunction(get(BLEND_FUNCTION_COLOR)._integer); }
void setBlendFunctionAlpha(BlendFunction function) { set(BLEND_FUNCTION_ALPHA, function.raw()); }
BlendFunction getBlendFunctionAlpha() const { return BlendFunction(get(BLEND_FUNCTION_ALPHA)._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); }
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:
State(const State& state);
State& operator=(const State& state);
FieldMap _fields;
Stamp _stamp;
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }

View file

@ -215,7 +215,13 @@ SunSkyStage::SunSkyStage() :
auto skyFromAtmosphereVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(SkyFromAtmosphere_vert)));
auto skyFromAtmosphereFragment = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(SkyFromAtmosphere_frag)));
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));
}

View file

@ -318,6 +318,29 @@ private:
int _blendNumber;
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 _normalMapProgram;
static gpu::ShaderPointer _specularMapProgram;
@ -473,6 +496,17 @@ private:
static AbstractViewStateInterface* _viewState;
/* class RenderKey {
public:
enum Flag {
TRANSLUCENT = 0,
HAS_LIGHTMAP,
};
RenderMode mode;
};
*/
};
Q_DECLARE_METATYPE(QPointer<Model>)