diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 4b77ce21be..a77201591b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -29,7 +29,12 @@ class QDebug; namespace gpu { enum ReservedSlot { + +#ifdef WIN32 TRANSFORM_OBJECT_SLOT = 6, +#else + TRANSFORM_OBJECT_SLOT = 31, +#endif TRANSFORM_CAMERA_SLOT = 7, }; diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 27e1548180..7f37a73c57 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -334,6 +334,7 @@ protected: GLuint _objectBuffer { 0 }; GLuint _cameraBuffer { 0 }; GLuint _drawCallInfoBuffer { 0 }; + GLuint _objectBufferTexture { 0 }; size_t _cameraUboSize { 0 }; Transform _view; Mat4 _projection; diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index ab8dbaf021..8bd0d0927c 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -92,11 +92,19 @@ void makeBindings(GLBackend::GLShader* shader) { // now assign the ubo binding, then DON't relink! //Check for gpu specific uniform slotBindings +#ifdef WIN32 loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer"); if (loc >= 0) { glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT; } +#else + loc = glGetUniformLocation(glprogram, "transformObjectBuffer"); + if (loc >= 0) { + glProgramUniform1i(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); + shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT; + } +#endif loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer"); if (loc >= 0) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index c8e9d51ff9..52d1f071f7 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -62,6 +62,9 @@ void GLBackend::initTransform() { glGenBuffers(1, &_transform._objectBuffer); glGenBuffers(1, &_transform._cameraBuffer); glGenBuffers(1, &_transform._drawCallInfoBuffer); +#ifndef WIN32 + glGenTextures(1, &_transform._objectBufferTexture); +#endif size_t cameraSize = sizeof(TransformCamera); while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; @@ -72,6 +75,9 @@ void GLBackend::killTransform() { glDeleteBuffers(1, &_transform._objectBuffer); glDeleteBuffers(1, &_transform._cameraBuffer); glDeleteBuffers(1, &_transform._drawCallInfoBuffer); +#ifndef WIN32 + glDeleteTextures(1, &_transform._objectBufferTexture); +#endif } void GLBackend::syncTransformStateCache() { @@ -137,9 +143,15 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { bufferData.resize(byteSize); memcpy(bufferData.data(), batch._objects.data(), byteSize); +#ifdef WIN32 glBindBuffer(GL_SHADER_STORAGE_BUFFER, _objectBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); +#else + glBindBuffer(GL_TEXTURE_BUFFER, _objectBuffer); + glBufferData(GL_TEXTURE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_TEXTURE_BUFFER, 0); +#endif } if (!batch._namedData.empty()) { @@ -157,7 +169,13 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_ARRAY_BUFFER, 0); } +#ifdef WIN32 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); +#else + glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); + glBindTexture(GL_TEXTURE_BUFFER, _objectBufferTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _objectBuffer); +#endif CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 9dd641d54b..4708c20a55 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -37,12 +37,32 @@ struct TransformObject { in ivec2 _drawCallInfo; +<@if GLPROFILE == PC_GL @> layout(std140) buffer transformObjectBuffer { TransformObject _object[]; }; TransformObject getTransformObject() { return _object[_drawCallInfo.x]; } +<@else@> +uniform samplerBuffer transformObjectBuffer; + +TransformObject getTransformObject() { + int offset = 8 * _drawCallInfo.x; + TransformObject object; + object._model[0] = texelFetch(transformObjectBuffer, offset); + object._model[1] = texelFetch(transformObjectBuffer, offset + 1); + object._model[2] = texelFetch(transformObjectBuffer, offset + 2); + object._model[3] = texelFetch(transformObjectBuffer, offset + 3); + + object._modelInverse[0] = texelFetch(transformObjectBuffer, offset + 4); + object._modelInverse[1] = texelFetch(transformObjectBuffer, offset + 5); + object._modelInverse[2] = texelFetch(transformObjectBuffer, offset + 6); + object._modelInverse[3] = texelFetch(transformObjectBuffer, offset + 7); + + return object; +} +<@endif@> <@endfunc@>