Revisiting the rendering pipeline pick and trying to use our brand new gpu::Pipeline

This commit is contained in:
Sam Gateau 2015-03-24 14:58:41 -07:00
parent d857a36557
commit 6284159892
6 changed files with 254 additions and 314 deletions

View file

@ -102,16 +102,14 @@ void generateAntialiasedLineEnable(GLBackend::GLState::Commands& commands, bool
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 generateDepthTest(GLBackend::GLState::Commands& commands, State::DepthTest& test) {
if (!test._enabled) {
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDisable, GLenum(GL_DEPTH_TEST))));
} else {
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glEnable, GLenum(GL_DEPTH_TEST))));
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDepthMask, test._writeMask)));
commands.push_back(CommandPointer(new Command1E((Command1E::GLFunction)glDepthFunc, GL_COMPARISON_FUNCTIONS[test._function])));
}
}
void generateStencilEnable(GLBackend::GLState::Commands& commands, bool enable) {
@ -228,9 +226,6 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
bool depthBias = false;
bool depthEnabled = false;
bool depthState = false;
bool stencilEnabled = false;
bool stencilState = false;
@ -275,16 +270,11 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
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;
case State::DEPTH_TEST: {
generateDepthTest(object->_commands, State::DepthTest(field.second._integer));
break;
}
case State::STENCIL_ENABLE: {
stencilEnabled = bool(field.second._integer);
generateStencilEnable(object->_commands, stencilEnabled);
@ -337,11 +327,6 @@ GLBackend::GLState* GLBackend::syncGPUObject(const State& state) {
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());

View file

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

View file

@ -42,9 +42,7 @@ public:
MULTISAMPLE_ENABLE,
ANTIALISED_LINE_ENABLE,
DEPTH_ENABLE,
DEPTH_WRITE_MASK,
DEPTH_FUNC,
DEPTH_TEST,
STENCIL_ENABLE,
STENCIL_READ_MASK,
@ -149,6 +147,18 @@ public:
WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ),
};
class DepthTest {
public:
DepthTest(bool enable, bool writeMask, ComparisonFunction func) :
_function(func), _writeMask(writeMask), _enabled(enable) {}
uint8 _function = ALWAYS;
bool _writeMask = false;
bool _enabled = false;
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
};
class StencilTest {
public:
int8 _failOp = STENCIL_OP_KEEP;
@ -217,13 +227,12 @@ public:
bool getMultisampleEnable() const { return get(MULTISAMPLE_ENABLE)._integer; }
bool getAntialiasedLineEnable() const { return get(ANTIALISED_LINE_ENABLE)._integer; }
void setDepthEnable(bool enable) { set(DEPTH_ENABLE, enable); }
void setDepthWriteMask(bool enable) { set(DEPTH_WRITE_MASK, enable); }
void setDepthFunc(ComparisonFunction func) { set(DEPTH_FUNC, func); }
bool getDepthEnable() const { return get(DEPTH_ENABLE)._integer; }
bool getDepthWriteMask() const { return get(DEPTH_WRITE_MASK)._integer; }
ComparisonFunction getDepthFunc() const { return ComparisonFunction(get(DEPTH_FUNC)._integer); }
void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { set(DEPTH_TEST, DepthTest(enable, writeMask, func).getRaw()); }
DepthTest getDepthTest() const { return DepthTest(get(DEPTH_TEST)._integer); }
bool getDepthTestEnabled() const { return getDepthTest()._enabled; }
bool getDepthTestWriteMask() const { return getDepthTest()._writeMask; }
ComparisonFunction getDepthTestFunc() const { return ComparisonFunction(getDepthTest()._function); }
void setStencilEnable(bool enable) { set(STENCIL_ENABLE, enable); }
void setStencilReadMask(uint8 mask) { set(STENCIL_READ_MASK, mask); }
void setStencilWriteMask(uint8 mask) { set(STENCIL_WRITE_MASK, mask); }

View file

@ -217,7 +217,6 @@ SunSkyStage::SunSkyStage() :
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyFromAtmosphereVertex, skyFromAtmosphereFragment));
auto skyState = gpu::StatePointer(new gpu::State());
skyState->setDepthEnable(false);
skyState->setStencilEnable(false);
skyState->setBlendEnable(false);

View file

@ -94,48 +94,81 @@ Model::~Model() {
deleteGeometry();
}
gpu::ShaderPointer Model::_program;
gpu::ShaderPointer Model::_normalMapProgram;
gpu::ShaderPointer Model::_specularMapProgram;
gpu::ShaderPointer Model::_normalSpecularMapProgram;
gpu::ShaderPointer Model::_translucentProgram;
Model::RenderPipelineLib Model::_renderPipelineLib;
const GLint MATERIAL_GPU_SLOT = 3;
gpu::ShaderPointer Model::_lightmapProgram;
gpu::ShaderPointer Model::_lightmapNormalMapProgram;
gpu::ShaderPointer Model::_lightmapSpecularMapProgram;
gpu::ShaderPointer Model::_lightmapNormalSpecularMapProgram;
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey& key,
gpu::ShaderPointer& vertexShader,
gpu::ShaderPointer& pixelShader ) {
gpu::ShaderPointer Model::_shadowProgram;
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
gpu::ShaderPointer Model::_skinProgram;
gpu::ShaderPointer Model::_skinNormalMapProgram;
gpu::ShaderPointer Model::_skinSpecularMapProgram;
gpu::ShaderPointer Model::_skinNormalSpecularMapProgram;
gpu::ShaderPointer Model::_skinTranslucentProgram;
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
bool makeResult = gpu::Shader::makeProgram(*program, slotBindings);
Locations* locations = new Locations();
initLocations(program, *locations);
gpu::ShaderPointer Model::_skinShadowProgram;
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
if (key.isShadow()) {
state->setCullMode(gpu::State::CULL_FRONT);
} else {
state->setCullMode(gpu::State::CULL_BACK);
}
Model::Locations Model::_locations;
Model::Locations Model::_normalMapLocations;
Model::Locations Model::_specularMapLocations;
Model::Locations Model::_normalSpecularMapLocations;
Model::Locations Model::_translucentLocations;
if (key.isTranslucent()) {
} else {
state->setBlendEnable(false);
}
Model::Locations Model::_lightmapLocations;
Model::Locations Model::_lightmapNormalMapLocations;
Model::Locations Model::_lightmapSpecularMapLocations;
Model::Locations Model::_lightmapNormalSpecularMapLocations;
/*
GLBATCH(glDisable)(GL_BLEND);
GLBATCH(glEnable)(GL_ALPHA_TEST);
if (mode == SHADOW_RENDER_MODE) {
GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f);
}
*/
Model::SkinLocations Model::_skinLocations;
Model::SkinLocations Model::_skinNormalMapLocations;
Model::SkinLocations Model::_skinSpecularMapLocations;
Model::SkinLocations Model::_skinNormalSpecularMapLocations;
Model::SkinLocations Model::_skinShadowLocations;
Model::SkinLocations Model::_skinTranslucentLocations;
auto it = insert(value_type(key.getRaw(),
RenderPipeline(
gpu::PipelinePointer( gpu::Pipeline::create(program, state) ),
std::shared_ptr<Locations>(locations)
)));
}
void Model::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, Model::Locations& locations) {
locations.alphaThreshold = program->getUniforms().findLocation("alphaThreshold");
locations.texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices");
locations.emissiveParams = program->getUniforms().findLocation("emissiveParams");
locations.glowIntensity = program->getUniforms().findLocation("glowIntensity");
locations.specularTextureUnit = program->getTextures().findLocation("specularMap");
locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
#if (GPU_FEATURE_PROFILE == GPU_CORE)
locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
#else
locations.materialBufferUnit = program->getUniforms().findLocation("materialBuffer");
#endif
locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices");
locations.clusterIndices = program->getInputs().findLocation("clusterIndices");;
locations.clusterWeights = program->getInputs().findLocation("clusterWeights");;
}
AbstractViewStateInterface* Model::_viewState = NULL;
const GLint MATERIAL_GPU_SLOT = 3;
void Model::setScale(const glm::vec3& scale) {
setScaleInternal(scale);
@ -167,33 +200,6 @@ void Model::setOffset(const glm::vec3& offset) {
_snappedToRegistrationPoint = false;
}
void Model::initProgram(gpu::ShaderPointer& program, Model::Locations& locations) {
locations.alphaThreshold = program->getUniforms().findLocation("alphaThreshold");
locations.texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices");
locations.emissiveParams = program->getUniforms().findLocation("emissiveParams");
locations.glowIntensity = program->getUniforms().findLocation("glowIntensity");
locations.specularTextureUnit = program->getTextures().findLocation("specularMap");
locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap");
#if (GPU_FEATURE_PROFILE == GPU_CORE)
locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
#else
locations.materialBufferUnit = program->getUniforms().findLocation("materialBuffer");
#endif
}
void Model::initSkinProgram(gpu::ShaderPointer& program, Model::SkinLocations& locations) {
initProgram(program, locations);
locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices");
locations.clusterIndices = program->getInputs().findLocation("clusterIndices");;
locations.clusterWeights = program->getInputs().findLocation("clusterWeights");;
}
QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
QVector<JointState> jointStates;
for (int i = 0; i < geometry.joints.size(); ++i) {
@ -227,7 +233,7 @@ void Model::initJointTransforms() {
}
void Model::init() {
if (_program.isNull()) {
if (_renderPipelineLib.empty()) {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
@ -257,74 +263,69 @@ void Model::init() {
auto modelLightmapSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag)));
auto modelLightmapNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag)));
// Fill the renderPipelineLib
_renderPipelineLib.addRenderPipeline(
RenderKey(0),
modelVertex, modelPixel);
bool makeResult = false;
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_TANGENTS),
modelNormalMapVertex, modelNormalMapPixel);
// Programs
_program = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*_program, slotBindings);
initProgram(_program, _locations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_SPECULAR),
modelVertex, modelSpecularMapPixel);
_normalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*_normalMapProgram, slotBindings);
initProgram(_normalMapProgram, _normalMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
modelNormalMapVertex, modelNormalSpecularMapPixel);
_specularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_specularMapProgram, slotBindings);
initProgram(_specularMapProgram, _specularMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_TRANSLUCENT),
modelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_DEPTH_ONLY),
modelShadowVertex, modelShadowPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_LIGHTMAP),
modelLightmapVertex, modelLightmapPixel);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS),
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
_normalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_normalSpecularMapProgram, slotBindings);
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_SPECULAR),
modelLightmapVertex, modelLightmapSpecularMapPixel);
_translucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelTranslucentPixel));
makeResult = gpu::Shader::makeProgram(*_translucentProgram, slotBindings);
initProgram(_translucentProgram, _translucentLocations);
_shadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelShadowVertex, modelShadowPixel));
makeResult = gpu::Shader::makeProgram(*_shadowProgram, slotBindings);
Model::Locations tempShadowLoc;
initProgram(_shadowProgram, tempShadowLoc);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
_lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapProgram, slotBindings);
initProgram(_lightmapProgram, _lightmapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED),
skinModelVertex, modelPixel);
_lightmapNormalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapNormalMapProgram, slotBindings);
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS),
skinModelNormalMapVertex, modelNormalMapPixel);
_lightmapSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapSpecularMapProgram, slotBindings);
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR),
skinModelVertex, modelSpecularMapPixel);
_lightmapNormalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapNormalSpecularMapProgram, slotBindings);
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
_skinProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*_skinProgram, slotBindings);
initSkinProgram(_skinProgram, _skinLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY),
skinModelShadowVertex, modelShadowPixel);
_skinNormalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelNormalMapVertex, modelNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*_skinNormalMapProgram, slotBindings);
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
_skinSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_skinSpecularMapProgram, slotBindings);
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
_skinNormalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelNormalMapVertex, modelNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_skinNormalSpecularMapProgram, slotBindings);
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations);
_skinShadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelShadowVertex, modelShadowPixel));
makeResult = gpu::Shader::makeProgram(*_skinShadowProgram, slotBindings);
initSkinProgram(_skinShadowProgram, _skinShadowLocations);
_skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel));
makeResult = gpu::Shader::makeProgram(*_skinTranslucentProgram, slotBindings);
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
_renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT),
skinModelVertex, modelTranslucentPixel);
}
}
@ -2249,81 +2250,24 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
Locations*& locations, SkinLocations*& skinLocations) {
gpu::ShaderPointer program = _program;
locations = &_locations;
gpu::ShaderPointer skinProgram = _skinProgram;
skinLocations = &_skinLocations;
if (mode == SHADOW_RENDER_MODE) {
program = _shadowProgram;
skinProgram = _skinShadowProgram;
skinLocations = &_skinShadowLocations;
} else if (translucent && alphaThreshold == 0.0f) {
program = _translucentProgram;
locations = &_translucentLocations;
skinProgram = _skinTranslucentProgram;
skinLocations = &_skinTranslucentLocations;
} else if (hasLightmap) {
if (hasTangents) {
if (hasSpecular) {
program = _lightmapNormalSpecularMapProgram;
locations = &_lightmapNormalSpecularMapLocations;
skinProgram.reset();
skinLocations = NULL;
} else {
program = _lightmapNormalMapProgram;
locations = &_lightmapNormalMapLocations;
skinProgram.reset();
skinLocations = NULL;
}
} else if (hasSpecular) {
program = _lightmapSpecularMapProgram;
locations = &_lightmapSpecularMapLocations;
skinProgram.reset();
skinLocations = NULL;
} else {
program = _lightmapProgram;
locations = &_lightmapLocations;
skinProgram.reset();
skinLocations = NULL;
}
} else {
if (hasTangents) {
if (hasSpecular) {
program = _normalSpecularMapProgram;
locations = &_normalSpecularMapLocations;
skinProgram = _skinNormalSpecularMapProgram;
skinLocations = &_skinNormalSpecularMapLocations;
} else {
program = _normalMapProgram;
locations = &_normalMapLocations;
skinProgram = _skinNormalMapProgram;
skinLocations = &_skinNormalMapLocations;
}
} else if (hasSpecular) {
program = _specularMapProgram;
locations = &_specularMapLocations;
skinProgram = _skinSpecularMapProgram;
skinLocations = &_skinSpecularMapLocations;
}
}
Locations*& locations) {
gpu::ShaderPointer activeProgram = program;
Locations* activeLocations = locations;
if (isSkinned) {
activeProgram = skinProgram;
activeLocations = skinLocations;
locations = skinLocations;
RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
auto pipeline = _renderPipelineLib.find(key.getRaw());
if (pipeline == _renderPipelineLib.end()) {
qDebug() << "No good, couldn;t find a pipeline from the key ?" << key.getRaw();
return;
}
GLuint glprogram = gpu::GLBackend::getShaderID(activeProgram);
gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram();
locations = (*pipeline).second._locations.get();
GLuint glprogram = gpu::GLBackend::getShaderID(program);
GLBATCH(glUseProgram)(glprogram);
if ((activeLocations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) {
GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold);
if ((locations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) {
GLBATCH(glUniform1f)(locations->alphaThreshold, alphaThreshold);
}
}
@ -2335,7 +2279,6 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
bool pickProgramsNeeded = true;
Locations* locations;
SkinLocations* skinLocations;
foreach(Model* model, _modelsInScene) {
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
@ -2343,11 +2286,11 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
QVector<int>& list = *whichList;
if (list.size() > 0) {
if (pickProgramsNeeded) {
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations);
pickProgramsNeeded = false;
}
model->setupBatchTransform(batch);
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations);
}
}
}
@ -2379,11 +2322,10 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
}
Locations* locations;
SkinLocations* skinLocations;
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
args, locations, skinLocations);
args, locations);
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
args, locations, skinLocations, forceRenderSomeMeshes);
args, locations, forceRenderSomeMeshes);
GLBATCH(glUseProgram)(0);
return meshPartsRendered;
@ -2391,7 +2333,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) {
Locations* locations, bool forceRenderSomeMeshes) {
PROFILE_RANGE(__FUNCTION__);
auto textureCache = DependencyManager::get<TextureCache>();
@ -2462,7 +2404,7 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
const MeshState& state = _meshStates.at(i);
if (state.clusterMatrices.size() > 1) {
GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
(const float*)state.clusterMatrices.constData());
batch.setModelTransform(Transform());
} else {

View file

@ -18,12 +18,16 @@
#include <QObject>
#include <QUrl>
#include <unordered_map>
#include <functional>
#include <AABox.h>
#include <AnimationCache.h>
#include <DependencyManager.h>
#include <GeometryUtil.h>
#include <gpu/Stream.h>
#include <gpu/Batch.h>
#include <gpu/Pipeline.h>
#include "PhysicsEntity.h"
#include <Transform.h>
@ -318,50 +322,6 @@ 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;
static gpu::ShaderPointer _normalSpecularMapProgram;
static gpu::ShaderPointer _translucentProgram;
static gpu::ShaderPointer _lightmapProgram;
static gpu::ShaderPointer _lightmapNormalMapProgram;
static gpu::ShaderPointer _lightmapSpecularMapProgram;
static gpu::ShaderPointer _lightmapNormalSpecularMapProgram;
static gpu::ShaderPointer _shadowProgram;
static gpu::ShaderPointer _skinProgram;
static gpu::ShaderPointer _skinNormalMapProgram;
static gpu::ShaderPointer _skinSpecularMapProgram;
static gpu::ShaderPointer _skinNormalSpecularMapProgram;
static gpu::ShaderPointer _skinTranslucentProgram;
static gpu::ShaderPointer _skinShadowProgram;
class Locations {
public:
int tangent;
@ -372,38 +332,10 @@ private:
int emissiveParams;
int glowIntensity;
int materialBufferUnit;
};
static Locations _locations;
static Locations _normalMapLocations;
static Locations _specularMapLocations;
static Locations _normalSpecularMapLocations;
static Locations _translucentLocations;
static Locations _lightmapLocations;
static Locations _lightmapNormalMapLocations;
static Locations _lightmapSpecularMapLocations;
static Locations _lightmapNormalSpecularMapLocations;
static void initProgram(ProgramObject& program, Locations& locations, bool link = true);
static void initProgram(gpu::ShaderPointer& program, Locations& locations);
class SkinLocations : public Locations {
public:
int clusterMatrices;
int clusterIndices;
int clusterWeights;
};
static SkinLocations _skinLocations;
static SkinLocations _skinNormalMapLocations;
static SkinLocations _skinSpecularMapLocations;
static SkinLocations _skinNormalSpecularMapLocations;
static SkinLocations _skinShadowLocations;
static SkinLocations _skinTranslucentLocations;
static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
static void initSkinProgram(gpu::ShaderPointer& program, SkinLocations& locations);
QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes
bool _calculatedMeshBoxesValid;
@ -489,12 +421,12 @@ private:
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
RenderArgs* args, Locations* locations, SkinLocations* skinLocations,
RenderArgs* args, Locations* locations,
bool forceRenderSomeMeshes = false);
static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
Locations*& locations, SkinLocations*& skinLocations);
Locations*& locations);
static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args);
@ -502,17 +434,90 @@ private:
static AbstractViewStateInterface* _viewState;
/* class RenderKey {
class RenderKey {
public:
enum Flag {
TRANSLUCENT = 0,
HAS_LIGHTMAP,
enum FlagBit {
IS_TRANSLUCENT_FLAG = 0,
HAS_LIGHTMAP_FLAG,
HAS_TANGENTS_FLAG,
HAS_SPECULAR_FLAG,
HAS_EMISSIVE_FLAG,
IS_SKINNED_FLAG,
IS_STEREO_FLAG,
IS_DEPTH_ONLY_FLAG,
IS_SHADOW_FLAG,
NUM_FLAGS,
};
enum Flag {
IS_TRANSLUCENT = (1 << IS_TRANSLUCENT_FLAG),
HAS_LIGHTMAP = (1 << HAS_LIGHTMAP_FLAG),
HAS_TANGENTS = (1 << HAS_TANGENTS_FLAG),
HAS_SPECULAR = (1 << HAS_SPECULAR_FLAG),
HAS_EMISSIVE = (1 << HAS_EMISSIVE_FLAG),
IS_SKINNED = (1 << IS_SKINNED_FLAG),
IS_STEREO = (1 << IS_STEREO_FLAG),
IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG),
IS_SHADOW = (1 << IS_SHADOW_FLAG),
RenderMode mode;
};
typedef unsigned short Flags;
bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); }
bool isTranslucent() const { return isFlag(IS_TRANSLUCENT); }
bool hasLightmap() const { return isFlag(HAS_LIGHTMAP); }
bool hasTangents() const { return isFlag(HAS_TANGENTS); }
bool HasSpecular() const { return isFlag(HAS_SPECULAR); }
bool HasEmissive() const { return isFlag(HAS_EMISSIVE); }
bool isSkinned() const { return isFlag(IS_SKINNED); }
bool isStereo() const { return isFlag(IS_STEREO); }
bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); }
bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing
Flags _flags = 0;
short _spare = 0;
int getRaw() { return *reinterpret_cast<int*>(this); }
RenderKey(RenderMode mode,
bool translucent, float alphaThreshold, bool hasLightmap,
bool hasTangents, bool hasSpecular, bool isSkinned) :
RenderKey( ((translucent && (alphaThreshold == 0.0f)) ? IS_TRANSLUCENT : 0)
| (hasLightmap && (mode != SHADOW_RENDER_MODE) ? HAS_LIGHTMAP : 0) // Lightmap, tangents and specular don't matter for depthOnly
| (hasTangents && (mode != SHADOW_RENDER_MODE) ? HAS_TANGENTS : 0)
| (hasSpecular && (mode != SHADOW_RENDER_MODE) ? HAS_SPECULAR : 0)
| (isSkinned ? IS_SKINNED : 0)
| ((mode == SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0)
| ((mode == SHADOW_RENDER_MODE) ? IS_SHADOW : 0)) {}
RenderKey(int bitmask) : _flags(bitmask) {}
};
*/
class RenderPipeline {
public:
gpu::PipelinePointer _pipeline;
std::shared_ptr<Locations> _locations;
RenderPipeline(gpu::PipelinePointer& pipeline, std::shared_ptr<Locations>& locations) :
_pipeline(pipeline), _locations(locations) {}
};
typedef std::unordered_map<int, RenderPipeline> BaseRenderPipelineMap;
class RenderPipelineLib : public BaseRenderPipelineMap {
public:
typedef RenderKey Key;
void addRenderPipeline(Key& key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
void initLocations(gpu::ShaderPointer& program, Locations& locations);
};
static RenderPipelineLib _renderPipelineLib;
};
Q_DECLARE_METATYPE(QPointer<Model>)