mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Revisiting the rendering pipeline pick and trying to use our brand new gpu::Pipeline
This commit is contained in:
parent
d857a36557
commit
6284159892
6 changed files with 254 additions and 314 deletions
|
@ -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());
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>)
|
||||
|
|
Loading…
Reference in a new issue