Transition model shaders to gpu:Shader

This commit is contained in:
Sam Gateau 2015-03-18 15:57:01 -07:00
parent 5a40fcee17
commit 0bd78be7f4
7 changed files with 507 additions and 224 deletions

View file

@ -56,8 +56,11 @@ enum Primitive {
};
enum ReservedSlot {
TRANSFORM_OBJECT_SLOT = 6,
/* TRANSFORM_OBJECT_SLOT = 6,
TRANSFORM_CAMERA_SLOT = 7,
*/
TRANSFORM_OBJECT_SLOT = 1,
TRANSFORM_CAMERA_SLOT = 2,
};
class Batch {

View file

@ -41,6 +41,12 @@ void makeBindings(GLBackend::GLShader* shader) {
glBindAttribLocation(glprogram, gpu::Stream::POSITION, "position");
}
//Check for gpu specific attribute slotBindings
loc = glGetAttribLocation(glprogram, "gl_Vertex");
if (loc >= 0) {
glBindAttribLocation(glprogram, gpu::Stream::POSITION, "position");
}
loc = glGetAttribLocation(glprogram, "normal");
if (loc >= 0) {
glBindAttribLocation(glprogram, gpu::Stream::NORMAL, "normal");
@ -520,18 +526,32 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, S
// The uniform as a standard var type
if (location != INVALID_UNIFORM_LOCATION) {
// Let's make sure the name doesn't contains an array element
std::string sname(name);
auto foundBracket = sname.find_first_of('[');
if (foundBracket != std::string::npos) {
// std::string arrayname = sname.substr(0, foundBracket);
if (sname[foundBracket + 1] == '0') {
sname = sname.substr(0, foundBracket);
} else {
// skip this uniform since it's not the first element of an array
continue;
}
}
if (elementResource._resource == Resource::BUFFER) {
uniforms.insert(Shader::Slot(name, location, elementResource._element, elementResource._resource));
uniforms.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource));
} else {
// For texture/Sampler, the location is the actual binding value
GLint binding = -1;
glGetUniformiv(glprogram, location, &binding);
auto requestedBinding = slotBindings.find(std::string(name));
auto requestedBinding = slotBindings.find(std::string(sname));
if (requestedBinding != slotBindings.end()) {
if (binding != (*requestedBinding)._location) {
binding = (*requestedBinding)._location;
glUniform1i(location, binding);
glProgramUniform1i(glprogram, location, binding);
}
}

View file

@ -41,31 +41,51 @@ public:
Language _lang = GLSL;
};
static const uint32 INVALID_LOCATION = -1;
class Slot {
public:
std::string _name;
uint32 _location;
Element _element;
uint16 _resourceType;
std::string _name = ("");
int32 _location = INVALID_LOCATION;
Element _element = Element();
uint16 _resourceType = Resource::BUFFER;
Slot(const std::string& name, uint16 location, const Element& element, uint16 resourceType = Resource::BUFFER) :
Slot(const Slot&& s) : _name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType) {}
// Slot& operator&&(const Slot&& s) : _name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType) {}
Slot(const std::string& name, int32 location, const Element& element, uint16 resourceType = Resource::BUFFER) :
_name(name), _location(location), _element(element), _resourceType(resourceType) {}
Slot(const std::string& name) : _name(name) {}
};
class Binding {
public:
std::string _name;
uint32 _location;
Binding(const std::string&& name, uint32 loc = 0) : _name(name), _location(loc) {}
int32 _location;
Binding(const std::string&& name, int32 loc = INVALID_LOCATION) : _name(name), _location(loc) {}
};
template <typename T> class Less {
public:
bool operator() (const T& x, const T& y) const { return x._name < y._name; }
};
typedef std::set<Slot, Less<Slot>> SlotSet;
class SlotSet : public std::set<Slot, Less<Slot>> {
public:
const Slot&& findSlot(const std::string& name) const {
auto key = Slot(name);
auto found = static_cast<const std::set<Slot, Less<Slot>>*>(this)->find(key);
if (found != end()) {
return std::move((*found));
}
return std::move(key);
}
int32 findLocation(const std::string& name) const {
return findSlot(name)._location;
}
protected:
};
typedef std::set<Binding, Less<Binding>> BindingSet;

View file

@ -28,7 +28,7 @@ vec4 transformModelToClipPos(TransformCamera camera, TransformObject object, vec
vec4 epos = (object._model * pos) + vec4(-pos.w * camera._viewInverse[3].xyz, 0.0);
return camera._projectionViewUntranslated * epos;
// Equivalent to the following but hoppefully a bit more accurate
// return camera._projection * camera._view * object._model * pos;
//return camera._projection * camera._view * object._model * pos;
<@else@>
return gl_ModelViewProjectionMatrix * pos;
<@endif@>
@ -68,14 +68,47 @@ TransformCamera getTransformCamera() {
}
<@else@>
uniform vec4 transformObjectBuffer[7];
TransformObject getTransformObject() {
TransformObject object;
object._model[0] = transformObjectBuffer[0];
object._model[1] = transformObjectBuffer[1];
object._model[2] = transformObjectBuffer[2];
object._model[3] = transformObjectBuffer[3];
object._modelInverse[0] = transformObjectBuffer[4];
object._modelInverse[1] = transformObjectBuffer[5];
object._modelInverse[2] = transformObjectBuffer[6];
object._modelInverse[3] = transformObjectBuffer[7];
return object;
}
uniform vec4 transformCameraBuffer[17];
TransformCamera getTransformCamera() {
TransformCamera camera;
camera._view[0] = transformCameraBuffer[0];
camera._view[1] = transformCameraBuffer[1];
camera._view[2] = transformCameraBuffer[2];
camera._view[3] = transformCameraBuffer[3];
camera._viewInverse[0] = transformCameraBuffer[4];
camera._viewInverse[1] = transformCameraBuffer[5];
camera._viewInverse[2] = transformCameraBuffer[6];
camera._viewInverse[3] = transformCameraBuffer[7];
camera._projectionViewUntranslated[0] = transformCameraBuffer[8];
camera._projectionViewUntranslated[1] = transformCameraBuffer[9];
camera._projectionViewUntranslated[2] = transformCameraBuffer[10];
camera._projectionViewUntranslated[3] = transformCameraBuffer[11];
camera._projection[0] = transformCameraBuffer[12];
camera._projection[1] = transformCameraBuffer[13];
camera._projection[2] = transformCameraBuffer[14];
camera._projection[3] = transformCameraBuffer[15];
camera._viewport = transformCameraBuffer[16];
return camera;
}

View file

@ -498,8 +498,8 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit
#if (GPU_FEATURE_PROFILE == GPU_CORE)
loc = glGetUniformBlockIndex(program.programId(), "lightBuffer");
if (loc >= 0) {
glUniformBlockBinding(program.programId(), loc, 0);
locations.lightBufferUnit = 0;
glUniformBlockBinding(program.programId(), loc, 3);
locations.lightBufferUnit = 3;
} else {
locations.lightBufferUnit = -1;
}
@ -515,8 +515,8 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit
#if (GPU_FEATURE_PROFILE == GPU_CORE)
loc = glGetUniformBlockIndex(program.programId(), "atmosphereBufferUnit");
if (loc >= 0) {
glUniformBlockBinding(program.programId(), loc, 1);
locations.atmosphereBufferUnit = 1;
glUniformBlockBinding(program.programId(), loc, 4);
locations.atmosphereBufferUnit = 4;
} else {
locations.atmosphereBufferUnit = -1;
}

View file

@ -93,27 +93,66 @@ Model::Model(QObject* parent) :
Model::~Model() {
deleteGeometry();
}
/*
ProgramObject Model::_POprogram;
ProgramObject Model::_POnormalMapProgram;
ProgramObject Model::_POspecularMapProgram;
ProgramObject Model::_POnormalSpecularMapProgram;
ProgramObject Model::_POtranslucentProgram;
ProgramObject Model::_program;
ProgramObject Model::_normalMapProgram;
ProgramObject Model::_specularMapProgram;
ProgramObject Model::_normalSpecularMapProgram;
ProgramObject Model::_translucentProgram;
ProgramObject Model::_POlightmapProgram;
ProgramObject Model::_POlightmapNormalMapProgram;
ProgramObject Model::_POlightmapSpecularMapProgram;
ProgramObject Model::_POlightmapNormalSpecularMapProgram;
ProgramObject Model::_lightmapProgram;
ProgramObject Model::_lightmapNormalMapProgram;
ProgramObject Model::_lightmapSpecularMapProgram;
ProgramObject Model::_lightmapNormalSpecularMapProgram;
ProgramObject Model::_POshadowProgram;
ProgramObject Model::_shadowProgram;
ProgramObject Model::_POskinProgram;
ProgramObject Model::_POskinNormalMapProgram;
ProgramObject Model::_POskinSpecularMapProgram;
ProgramObject Model::_POskinNormalSpecularMapProgram;
ProgramObject Model::_POskinTranslucentProgram;
ProgramObject Model::_skinProgram;
ProgramObject Model::_skinNormalMapProgram;
ProgramObject Model::_skinSpecularMapProgram;
ProgramObject Model::_skinNormalSpecularMapProgram;
ProgramObject Model::_skinTranslucentProgram;
ProgramObject Model::_POskinShadowProgram;
ProgramObject Model::_skinShadowProgram;
Model::Locations Model::_POlocations;
Model::Locations Model::_POnormalMapLocations;
Model::Locations Model::_POspecularMapLocations;
Model::Locations Model::_POnormalSpecularMapLocations;
Model::Locations Model::_POtranslucentLocations;
Model::Locations Model::_POlightmapLocations;
Model::Locations Model::_POlightmapNormalMapLocations;
Model::Locations Model::_POlightmapSpecularMapLocations;
Model::Locations Model::_POlightmapNormalSpecularMapLocations;
Model::SkinLocations Model::_POskinLocations;
Model::SkinLocations Model::_POskinNormalMapLocations;
Model::SkinLocations Model::_POskinSpecularMapLocations;
Model::SkinLocations Model::_POskinNormalSpecularMapLocations;
Model::SkinLocations Model::_POskinShadowLocations;
Model::SkinLocations Model::_POskinTranslucentLocations;
*/
gpu::ShaderPointer Model::_program;
gpu::ShaderPointer Model::_normalMapProgram;
gpu::ShaderPointer Model::_specularMapProgram;
gpu::ShaderPointer Model::_normalSpecularMapProgram;
gpu::ShaderPointer Model::_translucentProgram;
gpu::ShaderPointer Model::_lightmapProgram;
gpu::ShaderPointer Model::_lightmapNormalMapProgram;
gpu::ShaderPointer Model::_lightmapSpecularMapProgram;
gpu::ShaderPointer Model::_lightmapNormalSpecularMapProgram;
gpu::ShaderPointer Model::_shadowProgram;
gpu::ShaderPointer Model::_skinProgram;
gpu::ShaderPointer Model::_skinNormalMapProgram;
gpu::ShaderPointer Model::_skinSpecularMapProgram;
gpu::ShaderPointer Model::_skinNormalSpecularMapProgram;
gpu::ShaderPointer Model::_skinTranslucentProgram;
gpu::ShaderPointer Model::_skinShadowProgram;
Model::Locations Model::_locations;
Model::Locations Model::_normalMapLocations;
@ -135,6 +174,8 @@ Model::SkinLocations Model::_skinTranslucentLocations;
AbstractViewStateInterface* Model::_viewState = NULL;
const GLint MATERIAL_GPU_SLOT = 3;
void Model::setScale(const glm::vec3& scale) {
setScaleInternal(scale);
// if anyone sets scale manually, then we are no longer scaled to fit
@ -165,6 +206,33 @@ 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.materialBuffer = 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");;
}
/*
void Model::initProgram(ProgramObject& program, Model::Locations& locations, bool link) {
if (link) {
program.bindAttributeLocation("tangent", gpu::Stream::TANGENT);
@ -203,8 +271,8 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo
#if (GPU_FEATURE_PROFILE == GPU_CORE)
loc = glGetUniformBlockIndex(program.programId(), "materialBuffer");
if (loc >= 0) {
glUniformBlockBinding(program.programId(), loc, 1);
locations.materialBufferUnit = 1;
glUniformBlockBinding(program.programId(), loc, MATERIAL_GPU_SLOT);
locations.materialBufferUnit = MATERIAL_GPU_SLOT;
} else {
locations.materialBufferUnit = -1;
}
@ -239,8 +307,8 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo
}
program.release();
}
}*/
/*
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) {
program.bindAttributeLocation("tangent", gpu::Stream::TANGENT);
program.bindAttributeLocation("texcoord1", gpu::Stream::TEXCOORD1);
@ -257,7 +325,7 @@ void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locati
locations.clusterWeights = program.attributeLocation("clusterWeights");
program.release();
}
}*/
QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
QVector<JointState> jointStates;
@ -292,10 +360,11 @@ void Model::initJointTransforms() {
}
void Model::init() {
if (!_program.isLinked()) {
/* //Work in progress not used yet
if (_program.isNull()) {
// if (!_program.isLinked()) {
//Work in progress not used yet
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), 1));
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));
@ -327,124 +396,142 @@ void Model::init() {
bool makeResult = false;
// Programs
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*program, slotBindings);
auto normalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*normalMapProgram, slotBindings);
auto specularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*specularMapProgram, slotBindings);
auto normalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*normalSpecularMapProgram, slotBindings);
auto translucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelTranslucentPixel));
makeResult = gpu::Shader::makeProgram(*translucentProgram, slotBindings);
auto shadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelShadowVertex, modelShadowPixel));
makeResult = gpu::Shader::makeProgram(*shadowProgram, slotBindings);
auto lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel));
makeResult = gpu::Shader::makeProgram(*lightmapProgram, slotBindings);
auto lightmapNormalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*lightmapNormalMapProgram, slotBindings);
auto lightmapSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*lightmapSpecularMapProgram, slotBindings);
auto lightmapNormalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*lightmapNormalSpecularMapProgram, slotBindings);
auto skinProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*skinProgram, slotBindings);
auto skinNormalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelNormalMapVertex, modelNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*skinNormalMapProgram, slotBindings);
auto skinSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*skinSpecularMapProgram, slotBindings);
auto skinNormalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelNormalMapVertex, modelNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*skinNormalSpecularMapProgram, slotBindings);
auto skinShadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelShadowVertex, modelShadowPixel));
makeResult = gpu::Shader::makeProgram(*skinShadowProgram, slotBindings);
auto skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel));
makeResult = gpu::Shader::makeProgram(*skinTranslucentProgram, slotBindings);
*/
_program.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_program.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
_program = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*_program, slotBindings);
initProgram(_program, _locations);
_normalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*_normalMapProgram, slotBindings);
initProgram(_normalMapProgram, _normalMapLocations);
_specularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelVertex, modelSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_specularMapProgram, slotBindings);
initProgram(_specularMapProgram, _specularMapLocations);
_normalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelNormalMapVertex, modelNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_normalSpecularMapProgram, slotBindings);
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
_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);
_lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapProgram, slotBindings);
initProgram(_lightmapProgram, _lightmapLocations);
_lightmapNormalMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapNormalMapProgram, slotBindings);
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
_lightmapSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapSpecularMapProgram, slotBindings);
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
_lightmapNormalSpecularMapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel));
makeResult = gpu::Shader::makeProgram(*_lightmapNormalSpecularMapProgram, slotBindings);
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
_skinProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelPixel));
makeResult = gpu::Shader::makeProgram(*_skinProgram, slotBindings);
initSkinProgram(_skinProgram, _skinLocations);
_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);
/*
_POprogram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_POprogram.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
initProgram(_POprogram, _POlocations);
_normalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
_normalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
initProgram(_normalMapProgram, _normalMapLocations);
_POnormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
_POnormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
initProgram(_POnormalMapProgram, _POnormalMapLocations);
_specularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_specularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
initProgram(_specularMapProgram, _specularMapLocations);
_POspecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_POspecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
initProgram(_POspecularMapProgram, _POspecularMapLocations);
_normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
_normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations);
_POnormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert);
_POnormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
initProgram(_POnormalSpecularMapProgram, _POnormalSpecularMapLocations);
_translucentProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_translucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
initProgram(_translucentProgram, _translucentLocations);
_POtranslucentProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_POtranslucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
initProgram(_POtranslucentProgram, _POtranslucentLocations);
// Lightmap
_lightmapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
_lightmapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_frag);
initProgram(_lightmapProgram, _lightmapLocations);
_POlightmapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
_POlightmapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_frag);
initProgram(_POlightmapProgram, _POlightmapLocations);
_lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
_lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_map_frag);
initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations);
_POlightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
_POlightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_map_frag);
initProgram(_POlightmapNormalMapProgramddd, _POlightmapNormalMapLocations);
_lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
_lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_specular_map_frag);
initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations);
_POlightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert);
_POlightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_specular_map_frag);
initProgram(_POlightmapSpecularMapProgram, _POlightmapSpecularMapLocations);
_lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
_lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_specular_map_frag);
initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations);
_POlightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert);
_POlightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_specular_map_frag);
initProgram(_POlightmapNormalSpecularMapProgram, _POlightmapNormalSpecularMapLocations);
// end lightmap
_shadowProgram.addShaderFromSourceCode(QGLShader::Vertex, model_shadow_vert);
_shadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
_POshadowProgram.addShaderFromSourceCode(QGLShader::Vertex, model_shadow_vert);
_POshadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
// Shadow program uses the same locations as standard rendering path but we still need to set the bindings
Model::Locations tempLoc;
initProgram(_shadowProgram, tempLoc);
initProgram(_POshadowProgram, tempLoc);
_skinProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
_skinProgram.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
initSkinProgram(_skinProgram, _skinLocations);
_POskinProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
_POskinProgram.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
initSkinProgram(_POskinProgram, _POskinLocations);
_skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
_skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations);
_POskinNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
_POskinNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag);
initSkinProgram(_POskinNormalMapProgram, _PaOskinNormalMapLocations);
_skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations);
_POskinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert);
_POskinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag);
initSkinProgram(_POskinSpecularMapProgram, _POskinSpecularMapLocations);
_skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
_skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations);
_POskinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert);
_POskinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag);
initSkinProgram(_POskinNormalSpecularMapProgram, _POskinNormalSpecularMapLocations);
_skinShadowProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_shadow_vert);
_skinShadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
initSkinProgram(_skinShadowProgram, _skinShadowLocations);
_POskinShadowProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_shadow_vert);
_POskinShadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
initSkinProgram(_POskinShadowProgram, _POskinShadowLocations);
_skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
_skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
_POskinTranslucentProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
_POskinTranslucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag);
initSkinProgram(_POskinTranslucentProgram, _POskinTranslucentLocations);
*/
}
}
@ -2302,83 +2389,165 @@ 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) {
ProgramObject* program = &_program;
locations = &_locations;
ProgramObject* 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;
/* if (false)
{
ProgramObject* program = &_POprogram;
locations = &_POlocations;
ProgramObject* skinProgram = &_POskinProgram;
skinLocations = &_POskinLocations;
if (mode == SHADOW_RENDER_MODE) {
program = &_POshadowProgram;
skinProgram = &_POskinShadowProgram;
skinLocations = &_POskinShadowLocations;
} else if (translucent && alphaThreshold == 0.0f) {
program = &_POtranslucentProgram;
locations = &_POtranslucentLocations;
skinProgram = &_POskinTranslucentProgram;
skinLocations = &_POskinTranslucentLocations;
} else if (hasLightmap) {
if (hasTangents) {
if (hasSpecular) {
program = &_lightmapNormalSpecularMapProgram;
locations = &_lightmapNormalSpecularMapLocations;
} else if (hasLightmap) {
if (hasTangents) {
if (hasSpecular) {
program = &_POlightmapNormalSpecularMapProgram;
locations = &_POlightmapNormalSpecularMapLocations;
skinProgram = NULL;
skinLocations = NULL;
} else {
program = &_POlightmapNormalMapProgram;
locations = &_POlightmapNormalMapLocations;
skinProgram = NULL;
skinLocations = NULL;
}
} else if (hasSpecular) {
program = &_POlightmapSpecularMapProgram;
locations = &_POlightmapSpecularMapLocations;
skinProgram = NULL;
skinLocations = NULL;
} else {
program = &_lightmapNormalMapProgram;
locations = &_lightmapNormalMapLocations;
program = &_POlightmapProgram;
locations = &_POlightmapLocations;
skinProgram = NULL;
skinLocations = NULL;
}
} else if (hasSpecular) {
program = &_lightmapSpecularMapProgram;
locations = &_lightmapSpecularMapLocations;
skinProgram = NULL;
skinLocations = NULL;
} else {
program = &_lightmapProgram;
locations = &_lightmapLocations;
skinProgram = NULL;
skinLocations = NULL;
}
} else {
if (hasTangents) {
if (hasSpecular) {
program = &_normalSpecularMapProgram;
locations = &_normalSpecularMapLocations;
skinProgram = &_skinNormalSpecularMapProgram;
skinLocations = &_skinNormalSpecularMapLocations;
} else {
program = &_normalMapProgram;
locations = &_normalMapLocations;
skinProgram = &_skinNormalMapProgram;
skinLocations = &_skinNormalMapLocations;
if (hasTangents) {
if (hasSpecular) {
program = &_POnormalSpecularMapProgram;
locations = &_POnormalSpecularMapLocations;
skinProgram = &_POskinNormalSpecularMapProgram;
skinLocations = &_POskinNormalSpecularMapLocations;
} else {
program = &_POnormalMapProgram;
locations = &_POnormalMapLocations;
skinProgram = &_POskinNormalMapProgram;
skinLocations = &_POskinNormalMapLocations;
}
} else if (hasSpecular) {
program = &_POspecularMapProgram;
locations = &_POspecularMapLocations;
skinProgram = &_POskinSpecularMapProgram;
skinLocations = &_POskinSpecularMapLocations;
}
} else if (hasSpecular) {
program = &_specularMapProgram;
locations = &_specularMapLocations;
skinProgram = &_skinSpecularMapProgram;
skinLocations = &_skinSpecularMapLocations;
}
ProgramObject* activeProgram = program;
Locations* activeLocations = locations;
if (isSkinned) {
activeProgram = skinProgram;
activeLocations = skinLocations;
locations = skinLocations;
}
// This code replace the "bind()" on the QGLProgram
if (!activeProgram->isLinked()) {
activeProgram->link();
}
}
ProgramObject* activeProgram = program;
Locations* activeLocations = locations;
if (isSkinned) {
activeProgram = skinProgram;
activeLocations = skinLocations;
locations = skinLocations;
}
// This code replace the "bind()" on the QGLProgram
if (!activeProgram->isLinked()) {
activeProgram->link();
}
GLBATCH(glUseProgram)(activeProgram->programId());
GLBATCH(glUseProgram)(activeProgram->programId());
if ((activeLocations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) {
GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold);
if ((activeLocations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) {
GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold);
}
}
else */
{
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(nullptr);
skinLocations = NULL;
} else {
program = _lightmapNormalMapProgram;
locations = &_lightmapNormalMapLocations;
skinProgram.reset(nullptr);
skinLocations = NULL;
}
} else if (hasSpecular) {
program = _lightmapSpecularMapProgram;
locations = &_lightmapSpecularMapLocations;
skinProgram.reset(nullptr);
skinLocations = NULL;
} else {
program = _lightmapProgram;
locations = &_lightmapLocations;
skinProgram.reset(nullptr);
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;
}
}
gpu::ShaderPointer activeProgram = program;
Locations* activeLocations = locations;
if (isSkinned) {
activeProgram = skinProgram;
activeLocations = skinLocations;
locations = skinLocations;
}
GLuint glprogram = gpu::GLBackend::getShaderID(activeProgram);
GLBATCH(glUseProgram)(glprogram);
if ((activeLocations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) {
GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold);
}
}
}

View file

@ -309,31 +309,49 @@ private:
int _blendNumber;
int _appliedBlendNumber;
/*
static ProgramObject _POprogram;
static ProgramObject _POnormalMapProgram;
static ProgramObject _POspecularMapProgram;
static ProgramObject _POnormalSpecularMapProgram;
static ProgramObject _POtranslucentProgram;
static ProgramObject _program;
static ProgramObject _normalMapProgram;
static ProgramObject _specularMapProgram;
static ProgramObject _normalSpecularMapProgram;
static ProgramObject _translucentProgram;
static ProgramObject _POlightmapProgram;
static ProgramObject _POlightmapNormalMapProgram;
static ProgramObject _POlightmapSpecularMapProgram;
static ProgramObject _POlightmapNormalSpecularMapProgram;
static ProgramObject _lightmapProgram;
static ProgramObject _lightmapNormalMapProgram;
static ProgramObject _lightmapSpecularMapProgram;
static ProgramObject _lightmapNormalSpecularMapProgram;
static ProgramObject _shadowProgram;
static ProgramObject _POshadowProgram;
static ProgramObject _skinProgram;
static ProgramObject _skinNormalMapProgram;
static ProgramObject _skinSpecularMapProgram;
static ProgramObject _skinNormalSpecularMapProgram;
static ProgramObject _skinTranslucentProgram;
static ProgramObject _POskinProgram;
static ProgramObject _POskinNormalMapProgram;
static ProgramObject _POskinSpecularMapProgram;
static ProgramObject _POskinNormalSpecularMapProgram;
static ProgramObject _POskinTranslucentProgram;
static ProgramObject _skinShadowProgram;
static ProgramObject _POskinShadowProgram;
*/
static gpu::ShaderPointer _program;
static gpu::ShaderPointer _normalMapProgram;
static gpu::ShaderPointer _specularMapProgram;
static gpu::ShaderPointer _normalSpecularMapProgram;
static gpu::ShaderPointer _translucentProgram;
static int _normalMapTangentLocation;
static int _normalSpecularMapTangentLocation;
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;
@ -356,8 +374,20 @@ private:
static Locations _lightmapNormalMapLocations;
static Locations _lightmapSpecularMapLocations;
static Locations _lightmapNormalSpecularMapLocations;
/*
static Locations _POlocations;
static Locations _POnormalMapLocations;
static Locations _POspecularMapLocations;
static Locations _POnormalSpecularMapLocations;
static Locations _POtranslucentLocations;
static Locations _POlightmapLocations;
static Locations _POlightmapNormalMapLocations;
static Locations _POlightmapSpecularMapLocations;
static Locations _POlightmapNormalSpecularMapLocations;
*/
static void initProgram(ProgramObject& program, Locations& locations, bool link = true);
static void initProgram(gpu::ShaderPointer& program, Locations& locations);
class SkinLocations : public Locations {
public:
@ -372,8 +402,16 @@ private:
static SkinLocations _skinNormalSpecularMapLocations;
static SkinLocations _skinShadowLocations;
static SkinLocations _skinTranslucentLocations;
/*
static SkinLocations _POskinLocations;
static SkinLocations _POskinNormalMapLocations;
static SkinLocations _POskinSpecularMapLocations;
static SkinLocations _POskinNormalSpecularMapLocations;
static SkinLocations _POskinShadowLocations;
static SkinLocations _POskinTranslucentLocations;
*/
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;