diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 84358b7ae1..3468e75738 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -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 { diff --git a/libraries/gpu/src/gpu/Config.slh b/libraries/gpu/src/gpu/Config.slh index b17bd7b2b8..7a51de594a 100644 --- a/libraries/gpu/src/gpu/Config.slh +++ b/libraries/gpu/src/gpu/Config.slh @@ -12,10 +12,16 @@ <@def GPU_CONFIG_SLH@> <@if GLPROFILE == PC_GL @> + <@def GPU_FEATURE_PROFILE GPU_CORE@> + <@def GPU_TRANSFORM_PROFILE GPU_CORE@> <@def VERSION_HEADER #version 330 compatibility@> <@elif GLPROFILE == MAC_GL @> + <@def GPU_FEATURE_PROFILE GPU_LEGACY@> + <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> <@def VERSION_HEADER #version 120@> <@else@> + <@def GPU_FEATURE_PROFILE GPU_LEGACY@> + <@def GPU_TRANSFORM_PROFILE GPU_LEGACY@> <@def VERSION_HEADER #version 120@> <@endif@> diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index eba904ae4f..aee3f009d1 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -55,19 +55,17 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); GLintptr rangeStart = batch._params[paramOffset + 1]._uint; GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint; -#if defined(Q_OS_MAC) + +#if (GPU_FEATURE_PROFILE == GPU_CORE) + GLuint bo = getBufferID(*uniformBuffer); + glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); +#else GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart); glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data); // NOT working so we ll stick to the uniform float array until we move to core profile // GLuint bo = getBufferID(*uniformBuffer); //glUniformBufferEXT(_shader._program, slot, bo); -#elif defined(Q_OS_WIN) - GLuint bo = getBufferID(*uniformBuffer); - glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); -#else - GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart); - glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data); #endif CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index 9bcc278d8e..bcfdc4f36c 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -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"); @@ -88,7 +94,7 @@ void makeBindings(GLBackend::GLShader* shader) { // now assign the ubo binding, then DON't relink! //Check for gpu specific uniform slotBindings -#if defined(Q_OS_WIN) +#if (GPU_TRANSFORM_PROFILE == GPU_CORE) loc = glGetUniformBlockIndex(glprogram, "transformObjectBuffer"); if (loc >= 0) { glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); @@ -503,6 +509,12 @@ ElementResource getFormatFromGLUniform(GLenum gltype) { int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) { GLint uniformsCount = 0; +#if (GPU_FEATURE_PROFILE == GPU_LEGACY) + GLint currentProgram = 0; + glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); + glUseProgram(glprogram); +#endif + glGetProgramiv(glprogram, GL_ACTIVE_UNIFORMS, &uniformsCount); for (int i = 0; i < uniformsCount; i++) { @@ -520,18 +532,36 @@ 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; +#if (GPU_FEATURE_PROFILE == GPU_LEGACY) glUniform1i(location, binding); +#else + glProgramUniform1i(glprogram, location, binding); +#endif } } @@ -541,6 +571,10 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, S } } +#if (GPU_FEATURE_PROFILE == GPU_LEGACY) + glUseProgram(currentProgram); +#endif + return uniformsCount; } @@ -551,7 +585,9 @@ bool isUnusedSlot(GLint binding) { int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& buffers) { GLint buffersCount = 0; -#if defined(Q_OS_WIN) + +#if (GPU_FEATURE_PROFILE == GPU_CORE) + glGetProgramiv(glprogram, GL_ACTIVE_UNIFORM_BLOCKS, &buffersCount); // fast exit diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 6e928bcf09..f0318a66aa 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -32,7 +32,7 @@ void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) { } void GLBackend::initTransform() { -#if defined(Q_OS_WIN) + #if (GPU_TRANSFORM_PROFILE == GPU_CORE) glGenBuffers(1, &_transform._transformObjectBuffer); glGenBuffers(1, &_transform._transformCameraBuffer); @@ -49,7 +49,7 @@ void GLBackend::initTransform() { } void GLBackend::killTransform() { -#if defined(Q_OS_WIN) + #if (GPU_TRANSFORM_PROFILE == GPU_CORE) glDeleteBuffers(1, &_transform._transformObjectBuffer); glDeleteBuffers(1, &_transform._transformCameraBuffer); #else @@ -77,34 +77,30 @@ void GLBackend::updateTransform() { _transform._transformCamera._projectionViewUntranslated = _transform._transformCamera._projection * viewUntranslated; } + #if (GPU_TRANSFORM_PROFILE == GPU_CORE) if (_transform._invalidView || _transform._invalidProj) { -#if defined(Q_OS_WIN) glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0); glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR(); -#endif } if (_transform._invalidModel) { -#if defined(Q_OS_WIN) glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, 0); glBindBuffer(GL_ARRAY_BUFFER, _transform._transformObjectBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformObject), (const void*) &_transform._transformObject, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR(); -#endif } -#if defined(Q_OS_WIN) glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _transform._transformObjectBuffer); glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, _transform._transformCameraBuffer); CHECK_GL_ERROR(); #endif -#if defined(Q_OS_MAC) || defined(Q_OS_LINUX) +#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY) // Do it again for fixed pipeline until we can get rid of it if (_transform._invalidProj) { if (_transform._lastMode != GL_PROJECTION) { diff --git a/libraries/gpu/src/gpu/GPUConfig.h b/libraries/gpu/src/gpu/GPUConfig.h index 5894d2a91d..0b2d93b18d 100644 --- a/libraries/gpu/src/gpu/GPUConfig.h +++ b/libraries/gpu/src/gpu/GPUConfig.h @@ -14,21 +14,32 @@ #define GL_GLEXT_PROTOTYPES 1 +#define GPU_CORE 1 +#define GPU_LEGACY 0 + #if defined(__APPLE__) #include #include +#define GPU_FEATURE_PROFILE GPU_LEGACY +#define GPU_TRANSFORM_PROFILE GPU_LEGACY + #elif defined(WIN32) #include #include #include +#define GPU_FEATURE_PROFILE GPU_CORE +#define GPU_TRANSFORM_PROFILE GPU_CORE + #elif defined(ANDROID) #else #include #include +#define GPU_FEATURE_PROFILE GPU_LEGACY +#define GPU_TRANSFORM_PROFILE GPU_LEGACY #endif diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index 9a5bec313b..c8db7cfd39 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -41,31 +41,58 @@ public: Language _lang = GLSL; }; + static const int32 INVALID_LOCATION = -1; + class Slot { public: std::string _name; - uint32 _location; + int32 _location{INVALID_LOCATION}; Element _element; - uint16 _resourceType; + 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(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) {} + + Slot& operator= (const Slot& s) { + _name = s._name; + _location = s._location; + _element = s._element; + _resourceType = s._resourceType; + return (*this); } }; 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 class Less { public: bool operator() (const T& x, const T& y) const { return x._name < y._name; } }; - typedef std::set> SlotSet; + + class SlotSet : public std::set> { + public: + Slot findSlot(const std::string& name) const { + auto key = Slot(name); + auto found = static_cast>*>(this)->find(key); + if (found != end()) { + return (*found); + } + return key; + } + int32 findLocation(const std::string& name) const { + return findSlot(name)._location; + } + protected: + }; + typedef std::set> BindingSet; diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index d3d2629c2e..042964f0f7 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -10,6 +10,7 @@ <@if not GPU_TRANSFORM_STATE_SLH@> <@def GPU_TRANSFORM_STATE_SLH@> +<@func declareStandardTransform()@> struct TransformObject { mat4 _model; mat4 _modelInverse; @@ -23,76 +24,100 @@ struct TransformCamera { vec4 _viewport; }; -vec4 transformModelToClipPos(TransformCamera camera, TransformObject object, vec4 pos) { -<@if GLPROFILE == MAC_GL@> - return gl_ModelViewProjectionMatrix * pos; -<@elif GLPROFILE == PC_GL@> - 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; -<@else@> - return gl_ModelViewProjectionMatrix * pos; -<@endif@> -} - -vec3 transformModelToEyeDir(TransformCamera camera, TransformObject object, vec3 dir) { -<@if GLPROFILE == MAC_GL@> - return gl_NormalMatrix * dir; -<@elif GLPROFILE == PC_GL@> - vec3 mr0 = vec3(object._modelInverse[0].x, object._modelInverse[1].x, object._modelInverse[2].x); - vec3 mr1 = vec3(object._modelInverse[0].y, object._modelInverse[1].y, object._modelInverse[2].y); - vec3 mr2 = vec3(object._modelInverse[0].z, object._modelInverse[1].z, object._modelInverse[2].z); - - vec3 mvc0 = vec3(dot(camera._viewInverse[0].xyz, mr0), dot(camera._viewInverse[0].xyz, mr1), dot(camera._viewInverse[0].xyz, mr2)); - vec3 mvc1 = vec3(dot(camera._viewInverse[1].xyz, mr0), dot(camera._viewInverse[1].xyz, mr1), dot(camera._viewInverse[1].xyz, mr2)); - vec3 mvc2 = vec3(dot(camera._viewInverse[2].xyz, mr0), dot(camera._viewInverse[2].xyz, mr1), dot(camera._viewInverse[2].xyz, mr2)); - - vec3 result = vec3(dot(mvc0, dir), dot(mvc1, dir), dot(mvc2, dir)); - - return result; -<@else@> - return gl_NormalMatrix * dir; -<@endif@> -} - -<@if GLPROFILE == PC_GL@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> uniform transformObjectBuffer { - TransformObject object; + TransformObject _object; }; TransformObject getTransformObject() { - return object; + return _object; } uniform transformCameraBuffer { - TransformCamera camera; + TransformCamera _camera; }; TransformCamera getTransformCamera() { - return camera; -} -<@elif GLPROFILE == MAC_GL@> -TransformObject getTransformObject() { - TransformObject object; - return object; + return _camera; } -TransformCamera getTransformCamera() { - TransformCamera camera; - return camera; -} <@else@> +//uniform vec4 transformObjectBuffer[8]; 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; } <@endif@> +<@endfunc@> +<@func transformModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + + { // transformModelToClipPos + vec4 _eyepos = (<$objectTransform$>._model * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0); + <$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos; + } +<@else@> + <$clipPos$> = gl_ModelViewProjectionMatrix * <$modelPos$>; +<@endif@> +<@endfunc@> + +<@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@> +<@if GPU_TRANSFORM_PROFILE == GPU_CORE@> + { // transformModelToEyeDir + vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x); + vec3 mr1 = vec3(<$objectTransform$>._modelInverse[0].y, <$objectTransform$>._modelInverse[1].y, <$objectTransform$>._modelInverse[2].y); + vec3 mr2 = vec3(<$objectTransform$>._modelInverse[0].z, <$objectTransform$>._modelInverse[1].z, <$objectTransform$>._modelInverse[2].z); + + vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2)); + vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2)); + vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2)); + + <$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>)); + } +<@else@> + <$eyeDir$> = gl_NormalMatrix * <$modelDir$>; +<@endif@> +<@endfunc@> + <@endif@> diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 2ef2bf3036..8f6c663668 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -252,27 +252,18 @@ public: // Schema to access the attribute values of the light class Schema { public: - Vec4 _position; - Vec3 _direction; - float _spare0; - Color _color; - float _intensity; - Vec4 _attenuation; - Vec4 _spot; - Vec4 _shadow; + Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f}; + Vec3 _direction{0.0f, 0.0f, -1.0f}; + float _spare0{0.0f}; + Color _color{1.0f}; + float _intensity{1.0f}; + Vec4 _attenuation{1.0f}; + Vec4 _spot{0.0f, 0.0f, 0.0f, 3.0f}; + Vec4 _shadow{0.0f}; - Vec4 _control; + Vec4 _control{0.0f}; - Schema() : - _position(0.0f, 0.0f, 0.0f, 1.0f), - _direction(0.0f, 0.0f, -1.0f), - _spare0(0.f), - _color(1.0f), - _intensity(1.0f), - _attenuation(1.0f, 1.0f, 1.0f, 1.0f), - _spot(0.0f, 0.0f, 0.0f, 3.0f), - _control(0.0f) - {} + Schema() {} }; const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index fc17e94050..41c6e075cf 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -19,7 +19,6 @@ struct Light { vec4 _spot; vec4 _shadow; - vec4 _control; }; @@ -65,29 +64,15 @@ float getLightShowContour(Light l) { return l._control.w; } -<@if GLPROFILE == PC_GL@> +<@if GPU_FEATURE_PROFILE == GPU_CORE @> uniform lightBuffer { Light light; }; Light getLight() { return light; } -<@elif GLPROFILE == MAC_GL@> -uniform vec4 lightBuffer[9]; -Light getLight() { - Light light; - light._position = lightBuffer[0]; - light._direction = lightBuffer[1]; - light._color = lightBuffer[2]; - light._attenuation = lightBuffer[3]; - light._spot = lightBuffer[4]; - light._shadow = lightBuffer[5]; - light._control = lightBuffer[6]; - - return light; -} <@else@> -uniform vec4 lightBuffer[9]; +uniform vec4 lightBuffer[7]; Light getLight() { Light light; light._position = lightBuffer[0]; diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index 2718b1dfa8..9262f23746 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -79,20 +79,15 @@ public: class Schema { public: - Color _diffuse; - float _opacity; - Color _specular; - float _shininess; - Color _emissive; - float _spare0; + Color _diffuse{0.5f}; + float _opacity{1.f}; + Color _specular{0.03f}; + float _shininess{0.1f}; + Color _emissive{0.0f}; + float _spare0{0.0f}; + glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4 - Schema() : - _diffuse(0.5f), - _opacity(1.0f), - _specular(0.03f), - _shininess(0.1f), - _emissive(0.0f) - {} + Schema() {} }; const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index 9ea269f214..6b8eea18a6 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -14,7 +14,8 @@ struct Material { vec4 _diffuse; vec4 _specular; - + vec4 _emissive; + vec4 _spare; }; float getMaterialOpacity(Material m) { return m._diffuse.a; } @@ -24,36 +25,21 @@ float getMaterialShininess(Material m) { return m._specular.a; } -<@if GLPROFILE == PC_GL@> +<@if GPU_FEATURE_PROFILE == GPU_CORE@> uniform materialBuffer { Material _mat; }; Material getMaterial() { return _mat; } -<@elif GLPROFILE == MAC_GL@> -uniform vec4 materialBuffer[2]; -Material getMaterial() { - Material mat; - mat._diffuse = materialBuffer[0]; - mat._specular = materialBuffer[1]; - return mat; -} - <@else@> -uniform vec4 materialBuffer[2]; +uniform vec4 materialBuffer[4]; Material getMaterial() { Material mat; mat._diffuse = materialBuffer[0]; mat._specular = materialBuffer[1]; + mat._emissive = materialBuffer[2]; + mat._spare = materialBuffer[3]; return mat; } <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 96ab790cd6..13bf947d71 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -494,18 +494,13 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.invViewMat = program.uniformLocation("invViewMat"); GLint loc = -1; -#if defined(Q_OS_MAC) - loc = program.uniformLocation("lightBuffer"); - if (loc >= 0) { - locations.lightBufferUnit = loc; - } else { - locations.lightBufferUnit = -1; - } -#elif defined(Q_OS_WIN) + +#if (GPU_FEATURE_PROFILE == GPU_CORE) + const GLint LIGHT_GPU_SLOT = 3; loc = glGetUniformBlockIndex(program.programId(), "lightBuffer"); if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, 0); - locations.lightBufferUnit = 0; + glUniformBlockBinding(program.programId(), loc, LIGHT_GPU_SLOT); + locations.lightBufferUnit = LIGHT_GPU_SLOT; } else { locations.lightBufferUnit = -1; } @@ -518,18 +513,12 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit } #endif -#if defined(Q_OS_MAC) - loc = program.uniformLocation("atmosphereBufferUnit"); - if (loc >= 0) { - locations.atmosphereBufferUnit = loc; - } else { - locations.atmosphereBufferUnit = -1; - } -#elif defined(Q_OS_WIN) +#if (GPU_FEATURE_PROFILE == GPU_CORE) + const GLint ATMOSPHERE_GPU_SLOT = 4; loc = glGetUniformBlockIndex(program.programId(), "atmosphereBufferUnit"); if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, 1); - locations.atmosphereBufferUnit = 1; + glUniformBlockBinding(program.programId(), loc, ATMOSPHERE_GPU_SLOT); + locations.atmosphereBufferUnit = ATMOSPHERE_GPU_SLOT; } else { locations.atmosphereBufferUnit = -1; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index d5e15ed2c8..0e0f081ec8 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -36,13 +36,13 @@ #include "Model.h" #include "model_vert.h" -#include "model_shadow_vert.h" -#include "model_normal_map_vert.h" -#include "model_lightmap_vert.h" -#include "model_lightmap_normal_map_vert.h" -#include "skin_model_vert.h" -#include "skin_model_shadow_vert.h" -#include "skin_model_normal_map_vert.h" +#include "model_shadow_vert.h" +#include "model_normal_map_vert.h" +#include "model_lightmap_vert.h" +#include "model_lightmap_normal_map_vert.h" +#include "skin_model_vert.h" +#include "skin_model_shadow_vert.h" +#include "skin_model_normal_map_vert.h" #include "model_frag.h" #include "model_shadow_frag.h" @@ -94,26 +94,26 @@ Model::~Model() { deleteGeometry(); } -ProgramObject Model::_program; -ProgramObject Model::_normalMapProgram; -ProgramObject Model::_specularMapProgram; -ProgramObject Model::_normalSpecularMapProgram; -ProgramObject Model::_translucentProgram; +gpu::ShaderPointer Model::_program; +gpu::ShaderPointer Model::_normalMapProgram; +gpu::ShaderPointer Model::_specularMapProgram; +gpu::ShaderPointer Model::_normalSpecularMapProgram; +gpu::ShaderPointer Model::_translucentProgram; -ProgramObject Model::_lightmapProgram; -ProgramObject Model::_lightmapNormalMapProgram; -ProgramObject Model::_lightmapSpecularMapProgram; -ProgramObject Model::_lightmapNormalSpecularMapProgram; +gpu::ShaderPointer Model::_lightmapProgram; +gpu::ShaderPointer Model::_lightmapNormalMapProgram; +gpu::ShaderPointer Model::_lightmapSpecularMapProgram; +gpu::ShaderPointer Model::_lightmapNormalSpecularMapProgram; -ProgramObject Model::_shadowProgram; +gpu::ShaderPointer Model::_shadowProgram; -ProgramObject Model::_skinProgram; -ProgramObject Model::_skinNormalMapProgram; -ProgramObject Model::_skinSpecularMapProgram; -ProgramObject Model::_skinNormalSpecularMapProgram; -ProgramObject Model::_skinTranslucentProgram; +gpu::ShaderPointer Model::_skinProgram; +gpu::ShaderPointer Model::_skinNormalMapProgram; +gpu::ShaderPointer Model::_skinSpecularMapProgram; +gpu::ShaderPointer Model::_skinNormalSpecularMapProgram; +gpu::ShaderPointer Model::_skinTranslucentProgram; -ProgramObject Model::_skinShadowProgram; +gpu::ShaderPointer Model::_skinShadowProgram; Model::Locations Model::_locations; Model::Locations Model::_normalMapLocations; @@ -135,6 +135,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,104 +167,31 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } -void Model::initProgram(ProgramObject& program, Model::Locations& locations, bool link) { - if (link) { - program.bindAttributeLocation("tangent", gpu::Stream::TANGENT); - program.bindAttributeLocation("texcoord1", gpu::Stream::TEXCOORD1); - program.link(); - } - program.bind(); +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.tangent = program.attributeLocation("tangent"); + locations.specularTextureUnit = program->getTextures().findLocation("specularMap"); + locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); - locations.alphaThreshold = program.uniformLocation("alphaThreshold"); - locations.texcoordMatrices = program.uniformLocation("texcoordMatrices"); - locations.emissiveParams = program.uniformLocation("emissiveParams"); - locations.glowIntensity = program.uniformLocation("glowIntensity"); - program.setUniformValue("diffuseMap", 0); - program.setUniformValue("normalMap", 1); - - int loc = program.uniformLocation("specularMap"); - if (loc >= 0) { - program.setUniformValue("specularMap", 2); - locations.specularTextureUnit = 2; - } else { - locations.specularTextureUnit = -1; - } - - loc = program.uniformLocation("emissiveMap"); - if (loc >= 0) { - program.setUniformValue("emissiveMap", 3); - locations.emissiveTextureUnit = 3; - } else { - locations.emissiveTextureUnit = -1; - } - - // bindable uniform version -#if defined(Q_OS_MAC) - loc = program.uniformLocation("materialBuffer"); - if (loc >= 0) { - locations.materialBufferUnit = loc; - } else { - locations.materialBufferUnit = -1; - } -#elif defined(Q_OS_WIN) - loc = glGetUniformBlockIndex(program.programId(), "materialBuffer"); - if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, 1); - locations.materialBufferUnit = 1; - } else { - locations.materialBufferUnit = -1; - } +#if (GPU_FEATURE_PROFILE == GPU_CORE) + locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); #else - loc = program.uniformLocation("materialBuffer"); - if (loc >= 0) { - locations.materialBufferUnit = loc; - } else { - locations.materialBufferUnit = -1; - } + locations.materialBufferUnit = program->getUniforms().findLocation("materialBuffer"); #endif -#if defined(Q_OS_WIN) - loc = glGetUniformBlockIndex(program.programId(), "transformObjectBuffer"); - if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, gpu::TRANSFORM_OBJECT_SLOT); - // locations.materialBufferUnit = 1; - } -#endif - -#if defined(Q_OS_WIN) - loc = glGetUniformBlockIndex(program.programId(), "transformCameraBuffer"); - if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, gpu::TRANSFORM_CAMERA_SLOT); - // locations.materialBufferUnit = 1; - } -#endif - - //program.link(); - if (!program.isLinked()) { - program.release(); - } - - program.release(); } -void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations) { - program.bindAttributeLocation("tangent", gpu::Stream::TANGENT); - program.bindAttributeLocation("texcoord1", gpu::Stream::TEXCOORD1); - program.bindAttributeLocation("clusterIndices", gpu::Stream::SKIN_CLUSTER_INDEX); - program.bindAttributeLocation("clusterWeights", gpu::Stream::SKIN_CLUSTER_WEIGHT); - program.link(); +void Model::initSkinProgram(gpu::ShaderPointer& program, Model::SkinLocations& locations) { - initProgram(program, locations, false); + initProgram(program, locations); - program.bind(); + locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); - locations.clusterMatrices = program.uniformLocation("clusterMatrices"); - locations.clusterIndices = program.attributeLocation("clusterIndices"); - locations.clusterWeights = program.attributeLocation("clusterWeights"); - - program.release(); + locations.clusterIndices = program->getInputs().findLocation("clusterIndices");; + locations.clusterWeights = program->getInputs().findLocation("clusterWeights");; } QVector Model::createJointStates(const FBXGeometry& geometry) { @@ -298,10 +227,9 @@ void Model::initJointTransforms() { } void Model::init() { - if (!_program.isLinked()) { -/* //Work in progress not used yet + if (_program.isNull()) { 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)); @@ -333,123 +261,69 @@ 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.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert); - _normalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag); - initProgram(_normalMapProgram, _normalMapLocations); - - _specularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert); - _specularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag); - initProgram(_specularMapProgram, _specularMapLocations); - - _normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_normal_map_vert); - _normalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag); - initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations); - - _translucentProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert); - _translucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag); - initProgram(_translucentProgram, _translucentLocations); - - // Lightmap - _lightmapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert); - _lightmapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_frag); - initProgram(_lightmapProgram, _lightmapLocations); - - _lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert); - _lightmapNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_map_frag); - initProgram(_lightmapNormalMapProgram, _lightmapNormalMapLocations); - - _lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_vert); - _lightmapSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_specular_map_frag); - initProgram(_lightmapSpecularMapProgram, _lightmapSpecularMapLocations); - - _lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_lightmap_normal_map_vert); - _lightmapNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_lightmap_normal_specular_map_frag); - initProgram(_lightmapNormalSpecularMapProgram, _lightmapNormalSpecularMapLocations); - // end lightmap - - - _shadowProgram.addShaderFromSourceCode(QGLShader::Vertex, model_shadow_vert); - _shadowProgram.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); - - _skinProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert); - _skinProgram.addShaderFromSourceCode(QGLShader::Fragment, model_frag); - initSkinProgram(_skinProgram, _skinLocations); - - _skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert); - _skinNormalMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_map_frag); - initSkinProgram(_skinNormalMapProgram, _skinNormalMapLocations); - - _skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, model_vert); - _skinSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_specular_map_frag); - initSkinProgram(_skinSpecularMapProgram, _skinSpecularMapLocations); - - _skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_normal_map_vert); - _skinNormalSpecularMapProgram.addShaderFromSourceCode(QGLShader::Fragment, model_normal_specular_map_frag); - initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations); - - _skinShadowProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_shadow_vert); - _skinShadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag); - initSkinProgram(_skinShadowProgram, _skinShadowLocations); - - - _skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert); - _skinTranslucentProgram.addShaderFromSourceCode(QGLShader::Fragment, model_translucent_frag); + + _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); } } @@ -2316,67 +2190,66 @@ QVector* 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; + gpu::ShaderPointer program = _program; locations = &_locations; - ProgramObject* skinProgram = &_skinProgram; + gpu::ShaderPointer skinProgram = _skinProgram; skinLocations = &_skinLocations; if (mode == SHADOW_RENDER_MODE) { - program = &_shadowProgram; - skinProgram = &_skinShadowProgram; + program = _shadowProgram; + skinProgram = _skinShadowProgram; skinLocations = &_skinShadowLocations; } else if (translucent && alphaThreshold == 0.0f) { - program = &_translucentProgram; + program = _translucentProgram; locations = &_translucentLocations; - skinProgram = &_skinTranslucentProgram; + skinProgram = _skinTranslucentProgram; skinLocations = &_skinTranslucentLocations; } else if (hasLightmap) { if (hasTangents) { if (hasSpecular) { - program = &_lightmapNormalSpecularMapProgram; + program = _lightmapNormalSpecularMapProgram; locations = &_lightmapNormalSpecularMapLocations; - skinProgram = NULL; + skinProgram.reset(); skinLocations = NULL; } else { - program = &_lightmapNormalMapProgram; + program = _lightmapNormalMapProgram; locations = &_lightmapNormalMapLocations; - skinProgram = NULL; + skinProgram.reset(); skinLocations = NULL; } } else if (hasSpecular) { - program = &_lightmapSpecularMapProgram; + program = _lightmapSpecularMapProgram; locations = &_lightmapSpecularMapLocations; - skinProgram = NULL; + skinProgram.reset(); skinLocations = NULL; } else { - program = &_lightmapProgram; + program = _lightmapProgram; locations = &_lightmapLocations; - skinProgram = NULL; + skinProgram.reset(); skinLocations = NULL; } } else { if (hasTangents) { if (hasSpecular) { - program = &_normalSpecularMapProgram; + program = _normalSpecularMapProgram; locations = &_normalSpecularMapLocations; - skinProgram = &_skinNormalSpecularMapProgram; + skinProgram = _skinNormalSpecularMapProgram; skinLocations = &_skinNormalSpecularMapLocations; } else { - program = &_normalMapProgram; + program = _normalMapProgram; locations = &_normalMapLocations; - skinProgram = &_skinNormalMapProgram; + skinProgram = _skinNormalMapProgram; skinLocations = &_skinNormalMapLocations; } } else if (hasSpecular) { - program = &_specularMapProgram; + program = _specularMapProgram; locations = &_specularMapLocations; - skinProgram = &_skinSpecularMapProgram; + skinProgram = _skinSpecularMapProgram; skinLocations = &_skinSpecularMapLocations; } } - ProgramObject* activeProgram = program; + gpu::ShaderPointer activeProgram = program; Locations* activeLocations = locations; if (isSkinned) { @@ -2384,12 +2257,10 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f activeLocations = skinLocations; locations = skinLocations; } - // This code replace the "bind()" on the QGLProgram - if (!activeProgram->isLinked()) { - activeProgram->link(); - } + + GLuint glprogram = gpu::GLBackend::getShaderID(activeProgram); + GLBATCH(glUseProgram)(glprogram); - GLBATCH(glUseProgram)(activeProgram->programId()); if ((activeLocations->alphaThreshold > -1) && (mode != SHADOW_RENDER_MODE)) { GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 890ea87d25..5114ef1c9f 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -318,31 +318,27 @@ private: int _blendNumber; int _appliedBlendNumber; + static gpu::ShaderPointer _program; + static gpu::ShaderPointer _normalMapProgram; + static gpu::ShaderPointer _specularMapProgram; + static gpu::ShaderPointer _normalSpecularMapProgram; + static gpu::ShaderPointer _translucentProgram; - static ProgramObject _program; - static ProgramObject _normalMapProgram; - static ProgramObject _specularMapProgram; - static ProgramObject _normalSpecularMapProgram; - static ProgramObject _translucentProgram; + static gpu::ShaderPointer _lightmapProgram; + static gpu::ShaderPointer _lightmapNormalMapProgram; + static gpu::ShaderPointer _lightmapSpecularMapProgram; + static gpu::ShaderPointer _lightmapNormalSpecularMapProgram; - static ProgramObject _lightmapProgram; - static ProgramObject _lightmapNormalMapProgram; - static ProgramObject _lightmapSpecularMapProgram; - static ProgramObject _lightmapNormalSpecularMapProgram; - - static ProgramObject _shadowProgram; + static gpu::ShaderPointer _shadowProgram; - static ProgramObject _skinProgram; - static ProgramObject _skinNormalMapProgram; - static ProgramObject _skinSpecularMapProgram; - static ProgramObject _skinNormalSpecularMapProgram; - static ProgramObject _skinTranslucentProgram; + static gpu::ShaderPointer _skinProgram; + static gpu::ShaderPointer _skinNormalMapProgram; + static gpu::ShaderPointer _skinSpecularMapProgram; + static gpu::ShaderPointer _skinNormalSpecularMapProgram; + static gpu::ShaderPointer _skinTranslucentProgram; - static ProgramObject _skinShadowProgram; + static gpu::ShaderPointer _skinShadowProgram; - static int _normalMapTangentLocation; - static int _normalSpecularMapTangentLocation; - class Locations { public: int tangent; @@ -365,8 +361,9 @@ private: 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: @@ -383,6 +380,7 @@ private: static SkinLocations _skinTranslucentLocations; static void initSkinProgram(ProgramObject& program, SkinLocations& locations); + static void initSkinProgram(gpu::ShaderPointer& program, SkinLocations& locations); QVector _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes bool _calculatedMeshBoxesValid; diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index d4c19915ff..2e75e2764c 100755 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -16,10 +16,8 @@ uniform sampler2DShadow shadowMap; // Fetching it float fetchShadow(vec3 texcoord) { -<@if GLPROFILE == PC_GL @> +<@if GPU_FEATURE_PROFILE == GPU_CORE @> return texture(shadowMap, texcoord); -<@elif GLPROFILE == MAC_GL@> - return shadow2D(shadowMap, texcoord).r; <@else@> return shadow2D(shadowMap, texcoord).r; <@endif@> diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 4f416e8f1f..21c9238273 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -12,10 +12,14 @@ // <@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + const int MAX_TEXCOORDS = 2; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; + // the interpolated normal varying vec4 normal; @@ -27,12 +31,11 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, gl_Vertex); - - // transform and store the normal for interpolation - normal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, normal.xyz)$> + normal = vec4(normalize(normal.xyz), 0.0); } diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index afe3c73549..f24ba4e53d 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -14,6 +14,8 @@ <@include gpu/Transform.slh@> +<$declareStandardTransform()$> + const int MAX_TEXCOORDS = 2; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; @@ -35,12 +37,12 @@ void main(void) { // interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0)).xy; interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(texcoord1.xy, 0.0, 1.0)).xy; - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, gl_Vertex); - - // transform and store the normal for interpolation - normal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, normal.xyz)$> + + normal = vec4(normalize(normal.xyz), 0.0); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slv b/libraries/render-utils/src/model_lightmap_normal_map.slv index 6e66b28e63..a1413b1530 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slv +++ b/libraries/render-utils/src/model_lightmap_normal_map.slv @@ -14,6 +14,8 @@ <@include gpu/Transform.slh@> +<$declareStandardTransform()$> + const int MAX_TEXCOORDS = 2; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; @@ -44,12 +46,13 @@ void main(void) { gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(texcoord1.xy, 0.0, 1.0)).xy; - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, gl_Vertex); - - // transform and store the normal for interpolation - interpolatedNormal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0); - interpolatedTangent = vec4(normalize(transformModelToEyeDir(cam, obj, tangent)), 0.0); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + <$transformModelToEyeDir(cam, obj, tangent, interpolatedTangent.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); + interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0); } diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index 4111458464..9983310b52 100755 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -13,6 +13,8 @@ // <@include gpu/Transform.slh@> + +<$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; @@ -38,12 +40,13 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, gl_Vertex); - - // transform and store the normal for interpolation - interpolatedNormal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0); - interpolatedTangent = vec4(normalize(transformModelToEyeDir(cam, obj, tangent)), 0.0); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + <$transformModelToEyeDir(cam, obj, tangent, interpolatedTangent.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); + interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0); } diff --git a/libraries/render-utils/src/model_shadow.slv b/libraries/render-utils/src/model_shadow.slv index 98f6bf5104..88e597557e 100755 --- a/libraries/render-utils/src/model_shadow.slv +++ b/libraries/render-utils/src/model_shadow.slv @@ -12,10 +12,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // <@include gpu/Transform.slh@> +<$declareStandardTransform()$> void main(void) { - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, gl_Vertex); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> } diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index 780b72323c..f65d5a8bdc 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -13,6 +13,7 @@ // <@include gpu/Transform.slh@> +<$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; const int MAX_CLUSTERS = 128; @@ -43,11 +44,11 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, position); - - // transform and store the normal for interpolation - normal = vec4(normalize(transformModelToEyeDir(cam, obj, normal.xyz)), 0.0); + <$transformModelToClipPos(cam, obj, position, gl_Position)$> + <$transformModelToEyeDir(cam, obj, normal.xyz, normal.xyz)$> + + normal = vec4(normalize(normal.xyz), 0.0); } diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index 43ec9c6a9d..6a4170152d 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -13,6 +13,7 @@ // <@include gpu/Transform.slh@> +<$declareStandardTransform()$> const int MAX_TEXCOORDS = 2; const int MAX_CLUSTERS = 128; @@ -44,22 +45,20 @@ void main(void) { interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; interpolatedTangent += clusterMatrix * vec4(tangent, 0.0) * clusterWeight; } - // interpolatedNormal = gl_ModelViewMatrix * interpolatedNormal; - // interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; - + // pass along the diffuse color gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); - gl_Position = gl_ModelViewProjectionMatrix * interpolatedPosition; - - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, interpolatedPosition); - - interpolatedNormal = vec4(normalize(transformModelToEyeDir(cam, obj, interpolatedNormal.xyz)), 0.0); - interpolatedTangent = vec4(normalize(transformModelToEyeDir(cam, obj, interpolatedTangent.xyz)), 0.0); + <$transformModelToClipPos(cam, obj, interpolatedPosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + <$transformModelToEyeDir(cam, obj, tangent, interpolatedTangent.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); + interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0); } diff --git a/libraries/render-utils/src/skin_model_shadow.slv b/libraries/render-utils/src/skin_model_shadow.slv index de7f8f4e9f..03b912a981 100755 --- a/libraries/render-utils/src/skin_model_shadow.slv +++ b/libraries/render-utils/src/skin_model_shadow.slv @@ -13,6 +13,7 @@ // <@include gpu/Transform.slh@> +<$declareStandardTransform()$> const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; @@ -30,8 +31,8 @@ void main(void) { position += clusterMatrix * gl_Vertex * clusterWeight; } - // use standard pipeline transform + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - gl_Position = transformModelToClipPos(cam, obj, position); + <$transformModelToClipPos(cam, obj, position, gl_Position)$> }