diff --git a/Package.swift b/Package.swift index f4f7ef34fd..9ec83531ee 100644 --- a/Package.swift +++ b/Package.swift @@ -192,6 +192,10 @@ let package = Package( name: "Hio", targets: ["Hio"] ), + .library( + name: "Glf", + targets: ["Glf"] + ), // ----- Pixar.UsdImaging ----- .library( name: "UsdShaders", @@ -368,6 +372,11 @@ let package = Package( type: .dynamic, targets: ["PyGarch"] ), + .library( + name: "PyGlf", + type: .dynamic, + targets: ["PyGlf"] + ), // ----------------- Apps ----- .executable( name: "UsdView", @@ -415,6 +424,7 @@ let package = Package( "PyCameraUtil", "PyPxOsd", "PyGarch", + "PyGlf", "PyUsdShaders", ] ), @@ -1386,6 +1396,31 @@ let package = Package( ] ), + .target( + name: "Glf", + dependencies: [ + .target(name: "Arch"), + .target(name: "Plug"), + .target(name: "Tf"), + .target(name: "Gf"), + .target(name: "Trace"), + .target(name: "Ar"), + .target(name: "Sdf"), + .target(name: "Garch"), + .target(name: "Hf"), + .target(name: "Hio"), + ], + resources: [ + .process("Resources") + ], + cxxSettings: [ + .define("MFB_PACKAGE_NAME", to: "Glf"), + .define("MFB_ALT_PACKAGE_NAME", to: "Glf"), + .define("MFB_PACKAGE_MODULE", to: "Glf"), + .define("GLF_EXPORTS", to: "1"), + ] + ), + .target( name: "PyTf", dependencies: [ @@ -1965,6 +2000,23 @@ let package = Package( ] ), + .target( + name: "PyGlf", + dependencies: [ + .target(name: "PixarUSD"), + ], + path: "Python/PyGlf", + resources: [ + .process("Resources"), + ], + publicHeadersPath: "include", + cxxSettings: [ + .define("MFB_PACKAGE_NAME", to: "Glf"), + .define("MFB_ALT_PACKAGE_NAME", to: "Glf"), + .define("MFB_PACKAGE_MODULE", to: "Glf"), + ] + ), + .executableTarget( name: "UsdView", dependencies: [ @@ -2066,6 +2118,7 @@ let package = Package( .target(name: "HgiGL"), .target(name: "HgiInterop"), .target(name: "Hio"), + .target(name: "Glf"), // --- usd imaging. ------ .target(name: "UsdShaders"), // -------- macros. ------ diff --git a/Sources/OpenUSD/imaging/glf/__init__.py b/Python/PyGlf/Resources/__init__.py similarity index 100% rename from Sources/OpenUSD/imaging/glf/__init__.py rename to Python/PyGlf/Resources/__init__.py diff --git a/Python/PyGlf/include/PyGlf.h b/Python/PyGlf/include/PyGlf.h new file mode 100644 index 0000000000..ceae3bdf1d --- /dev/null +++ b/Python/PyGlf/include/PyGlf.h @@ -0,0 +1,6 @@ +#ifndef __PXR_IMAGING_PY_GLF_H__ +#define __PXR_IMAGING_PY_GLF_H__ + +/* no includes. */ + +#endif // __PXR_IMAGING_PY_GLF_H__ diff --git a/Sources/OpenUSD/imaging/glf/module.cpp b/Python/PyGlf/module.cpp similarity index 85% rename from Sources/OpenUSD/imaging/glf/module.cpp rename to Python/PyGlf/module.cpp index 32e1eebc14..3e7b12a10c 100644 --- a/Sources/OpenUSD/imaging/glf/module.cpp +++ b/Python/PyGlf/module.cpp @@ -21,16 +21,16 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // -#include "pxr/pxr.h" -#include "pxr/base/tf/pyModule.h" +#include +#include "Tf/pyModule.h" PXR_NAMESPACE_USING_DIRECTIVE TF_WRAP_MODULE { - TF_WRAP( Diagnostic ); - TF_WRAP( DrawTarget ); - TF_WRAP( Texture ); - TF_WRAP( SimpleLight ); - TF_WRAP( SimpleMaterial ); + TF_WRAP(Diagnostic); + TF_WRAP(DrawTarget); + TF_WRAP(Texture); + TF_WRAP(SimpleLight); + TF_WRAP(SimpleMaterial); } diff --git a/Sources/OpenUSD/imaging/glf/moduleDeps.cpp b/Python/PyGlf/moduleDeps.cpp similarity index 66% rename from Sources/OpenUSD/imaging/glf/moduleDeps.cpp rename to Python/PyGlf/moduleDeps.cpp index 5f2fb668df..b3010177e5 100644 --- a/Sources/OpenUSD/imaging/glf/moduleDeps.cpp +++ b/Python/PyGlf/moduleDeps.cpp @@ -23,32 +23,29 @@ // //////////////////////////////////////////////////////////////////////// -#include "pxr/pxr.h" -#include "pxr/base/tf/registryManager.h" -#include "pxr/base/tf/scriptModuleLoader.h" -#include "pxr/base/tf/token.h" +#include +#include "Tf/registryManager.h" +#include "Tf/scriptModuleLoader.h" +#include "Tf/token.h" #include PXR_NAMESPACE_OPEN_SCOPE -TF_REGISTRY_FUNCTION(TfScriptModuleLoader) { - // List of direct dependencies for this library. - const std::vector reqs = { - TfToken("arch"), - TfToken("garch"), - TfToken("gf"), - TfToken("hf"), - TfToken("hio"), - TfToken("sdf"), - TfToken("tf"), - TfToken("trace"), - TfToken("vt") - }; - TfScriptModuleLoader::GetInstance(). - RegisterLibrary(TfToken("glf"), TfToken("pxr.Glf"), reqs); +TF_REGISTRY_FUNCTION(TfScriptModuleLoader) +{ + // List of direct dependencies for this library. + const std::vector reqs = { + TfToken("arch"), + TfToken("garch"), + TfToken("gf"), + TfToken("hf"), + TfToken("hio"), + TfToken("sdf"), + TfToken("tf"), + TfToken("trace"), + TfToken("vt")}; + TfScriptModuleLoader::GetInstance().RegisterLibrary(TfToken("glf"), TfToken("pxr.Glf"), reqs); } PXR_NAMESPACE_CLOSE_SCOPE - - diff --git a/Sources/OpenUSD/imaging/glf/wrapDiagnostic.cpp b/Python/PyGlf/wrapDiagnostic.cpp similarity index 64% rename from Sources/OpenUSD/imaging/glf/wrapDiagnostic.cpp rename to Python/PyGlf/wrapDiagnostic.cpp index b0dfb363dd..0e701167a2 100644 --- a/Sources/OpenUSD/imaging/glf/wrapDiagnostic.cpp +++ b/Python/PyGlf/wrapDiagnostic.cpp @@ -21,7 +21,7 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // -#include "pxr/imaging/glf/diagnostic.h" +#include "Glf/diagnostic.h" #include #include @@ -31,18 +31,18 @@ using namespace boost::python; PXR_NAMESPACE_USING_DIRECTIVE void wrapDiagnostic() -{ - def("RegisterDefaultDebugOutputMessageCallback", - &GlfRegisterDefaultDebugOutputMessageCallback); +{ + def("RegisterDefaultDebugOutputMessageCallback", + &GlfRegisterDefaultDebugOutputMessageCallback); - class_("GLQueryObject") - .def("Begin", &GlfGLQueryObject::Begin) - .def("BeginPrimitivesGenerated", &GlfGLQueryObject::BeginPrimitivesGenerated) - .def("BeginTimeElapsed", &GlfGLQueryObject::BeginTimeElapsed) - .def("BeginSamplesPassed", &GlfGLQueryObject::BeginSamplesPassed) - .def("End", &GlfGLQueryObject::End) - .def("GetResult", &GlfGLQueryObject::GetResult) - .def("GetResultNoWait", &GlfGLQueryObject::GetResultNoWait) + class_("GLQueryObject") + .def("Begin", &GlfGLQueryObject::Begin) + .def("BeginPrimitivesGenerated", &GlfGLQueryObject::BeginPrimitivesGenerated) + .def("BeginTimeElapsed", &GlfGLQueryObject::BeginTimeElapsed) + .def("BeginSamplesPassed", &GlfGLQueryObject::BeginSamplesPassed) + .def("End", &GlfGLQueryObject::End) + .def("GetResult", &GlfGLQueryObject::GetResult) + .def("GetResultNoWait", &GlfGLQueryObject::GetResultNoWait) - ; + ; } diff --git a/Sources/OpenUSD/imaging/glf/wrapDrawTarget.cpp b/Python/PyGlf/wrapDrawTarget.cpp similarity index 56% rename from Sources/OpenUSD/imaging/glf/wrapDrawTarget.cpp rename to Python/PyGlf/wrapDrawTarget.cpp index 4c160a6d86..b4fca41f5b 100644 --- a/Sources/OpenUSD/imaging/glf/wrapDrawTarget.cpp +++ b/Python/PyGlf/wrapDrawTarget.cpp @@ -21,12 +21,12 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // -#include "pxr/imaging/glf/drawTarget.h" +#include "Glf/drawTarget.h" -#include "pxr/base/tf/makePyConstructor.h" -#include "pxr/base/tf/pyPtrHelpers.h" -#include "pxr/base/tf/pyResultConversions.h" -#include "pxr/base/tf/pyEnum.h" +#include "Tf/makePyConstructor.h" +#include "Tf/pyPtrHelpers.h" +#include "Tf/pyResultConversions.h" +#include "Tf/pyEnum.h" #include #include @@ -36,40 +36,37 @@ using namespace boost::python; PXR_NAMESPACE_USING_DIRECTIVE -namespace { - -static GlfDrawTargetRefPtr _NewDrawTarget( - GfVec2i const & size) +namespace { + + static GlfDrawTargetRefPtr _NewDrawTarget( + GfVec2i const &size) + { return GlfDrawTarget::New(size); -} + } -static GlfDrawTargetRefPtr _NewDrawTarget2( - unsigned int width, unsigned int height) -{ + static GlfDrawTargetRefPtr _NewDrawTarget2( + unsigned int width, unsigned int height) + { return GlfDrawTarget::New(GfVec2i(width, height)); -} + } -} // anonymous namespace +} // anonymous namespace void wrapDrawTarget() { - typedef GlfDrawTarget This; - typedef GlfDrawTargetPtr ThisPtr; - - class_("DrawTarget", no_init) - .def(TfPyRefAndWeakPtr()) - .def("__init__",TfMakePyConstructor(&_NewDrawTarget)) - .def("__init__",TfMakePyConstructor(&_NewDrawTarget2)) - .def("AddAttachment", &This::AddAttachment) - .def("Bind", &This::Bind) - .def("Unbind", &This::Unbind) - .def("WriteToFile", - &This::WriteToFile, ( - arg("attachment"), - arg("filename"), - arg("viewMatrix") = GfMatrix4d(1), - arg("projectionMatrix") = GfMatrix4d(1))) - - ; + typedef GlfDrawTarget This; + typedef GlfDrawTargetPtr ThisPtr; + + class_("DrawTarget", no_init) + .def(TfPyRefAndWeakPtr()) + .def("__init__", TfMakePyConstructor(&_NewDrawTarget)) + .def("__init__", TfMakePyConstructor(&_NewDrawTarget2)) + .def("AddAttachment", &This::AddAttachment) + .def("Bind", &This::Bind) + .def("Unbind", &This::Unbind) + .def("WriteToFile", + &This::WriteToFile, (arg("attachment"), arg("filename"), arg("viewMatrix") = GfMatrix4d(1), arg("projectionMatrix") = GfMatrix4d(1))) + + ; } diff --git a/Python/PyGlf/wrapSimpleLight.cpp b/Python/PyGlf/wrapSimpleLight.cpp new file mode 100644 index 0000000000..35952f384d --- /dev/null +++ b/Python/PyGlf/wrapSimpleLight.cpp @@ -0,0 +1,132 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "Glf/simpleLight.h" + +#include + +using namespace boost::python; + +PXR_NAMESPACE_USING_DIRECTIVE + +void wrapSimpleLight() +{ + typedef GlfSimpleLight This; + + class_("SimpleLight", init<>()) + .add_property("transform", + make_function( + &This::GetTransform, + return_value_policy()), + &This::SetTransform) + .add_property("ambient", + make_function( + &This::GetAmbient, + return_value_policy()), + &This::SetAmbient) + .add_property("diffuse", + make_function( + &This::GetDiffuse, + return_value_policy()), + &This::SetDiffuse) + .add_property("specular", + make_function( + &This::GetSpecular, + return_value_policy()), + &This::SetSpecular) + .add_property("position", + make_function( + &This::GetPosition, + return_value_policy()), + &This::SetPosition) + .add_property("spotDirection", + make_function( + &This::GetSpotDirection, + return_value_policy()), + &This::SetSpotDirection) + .add_property("spotCutoff", + make_function( + &This::GetSpotCutoff, + return_value_policy()), + &This::SetSpotCutoff) + .add_property("spotFalloff", + make_function( + &This::GetSpotFalloff, + return_value_policy()), + &This::SetSpotFalloff) + .add_property("attenuation", + make_function( + &This::GetAttenuation, + return_value_policy()), + &This::SetAttenuation) + .add_property("shadowMatrices", + make_function( + &This::GetShadowMatrices, + return_value_policy()), + &This::SetShadowMatrices) + .add_property("shadowResolution", + make_function( + &This::GetShadowResolution, + return_value_policy()), + &This::SetShadowResolution) + .add_property("shadowBias", + make_function( + &This::GetShadowBias, + return_value_policy()), + &This::SetShadowBias) + .add_property("shadowBlur", + make_function( + &This::GetShadowBlur, + return_value_policy()), + &This::SetShadowBlur) + .add_property("shadowIndexStart", + make_function( + &This::GetShadowIndexStart, + return_value_policy()), + &This::SetShadowIndexStart) + .add_property("shadowIndexEnd", + make_function( + &This::GetShadowIndexEnd, + return_value_policy()), + &This::SetShadowIndexEnd) + .add_property("hasShadow", + make_function( + &This::HasShadow, + return_value_policy()), + &This::SetHasShadow) + .add_property("isCameraSpaceLight", + make_function( + &This::IsCameraSpaceLight, + return_value_policy()), + &This::SetIsCameraSpaceLight) + .add_property("id", + make_function( + &This::GetID, + return_value_policy()), + &This::SetID) + .add_property("isDomeLight", + make_function( + &This::IsDomeLight, + return_value_policy()), + &This::SetIsDomeLight); +} diff --git a/Python/PyGlf/wrapSimpleMaterial.cpp b/Python/PyGlf/wrapSimpleMaterial.cpp new file mode 100644 index 0000000000..1b6301a1d9 --- /dev/null +++ b/Python/PyGlf/wrapSimpleMaterial.cpp @@ -0,0 +1,62 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "Glf/simpleMaterial.h" + +#include + +using namespace boost::python; + +PXR_NAMESPACE_USING_DIRECTIVE + +void wrapSimpleMaterial() +{ + typedef GlfSimpleMaterial This; + + class_("SimpleMaterial", init<>()) + .add_property("ambient", + make_function( + &This::GetAmbient, + return_value_policy()), + &This::SetAmbient) + .add_property("diffuse", + make_function( + &This::GetDiffuse, + return_value_policy()), + &This::SetDiffuse) + .add_property("specular", + make_function( + &This::GetSpecular, + return_value_policy()), + &This::SetSpecular) + .add_property("emission", + make_function( + &This::GetEmission, + return_value_policy()), + &This::SetEmission) + .add_property("shininess", + make_function( + &This::GetShininess, + return_value_policy()), + &This::SetShininess); +} diff --git a/Sources/OpenUSD/imaging/glf/wrapTexture.cpp b/Python/PyGlf/wrapTexture.cpp similarity index 52% rename from Sources/OpenUSD/imaging/glf/wrapTexture.cpp rename to Python/PyGlf/wrapTexture.cpp index ba727a5aff..a973ec0a7e 100644 --- a/Sources/OpenUSD/imaging/glf/wrapTexture.cpp +++ b/Python/PyGlf/wrapTexture.cpp @@ -21,10 +21,10 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // -#include "pxr/imaging/glf/texture.h" +#include "Glf/texture.h" -#include "pxr/base/tf/makePyConstructor.h" -#include "pxr/base/tf/pyPtrHelpers.h" +#include "Tf/makePyConstructor.h" +#include "Tf/pyPtrHelpers.h" #include #include @@ -35,30 +35,27 @@ using namespace boost::python; PXR_NAMESPACE_USING_DIRECTIVE void wrapTexture() -{ - typedef GlfTexture This; - typedef GlfTexturePtr ThisPtr; +{ + typedef GlfTexture This; + typedef GlfTexturePtr ThisPtr; - class_( - "Texture", no_init) - .def("GetTextureMemoryAllocated", &This::GetTextureMemoryAllocated) - .staticmethod("GetTextureMemoryAllocated") + class_( + "Texture", no_init) + .def("GetTextureMemoryAllocated", &This::GetTextureMemoryAllocated) + .staticmethod("GetTextureMemoryAllocated") - .add_property( "memoryUsed", make_function( - &This::GetMemoryUsed, - return_value_policy())) + .add_property("memoryUsed", make_function( + &This::GetMemoryUsed, + return_value_policy())) - .add_property( "memoryRequested", make_function( - &This::GetMemoryRequested, - return_value_policy()), - &This::SetMemoryRequested) + .add_property("memoryRequested", make_function(&This::GetMemoryRequested, return_value_policy()), + &This::SetMemoryRequested) - .add_property( "minFilterSupported", make_function( - &This::IsMinFilterSupported, - return_value_policy())) + .add_property("minFilterSupported", make_function( + &This::IsMinFilterSupported, + return_value_policy())) - .add_property( "magFilterSupported", make_function( - &This::IsMagFilterSupported, - return_value_policy())) - ; + .add_property("magFilterSupported", make_function( + &This::IsMagFilterSupported, + return_value_policy())); } diff --git a/Sources/Glf/Glf.docc/Glf.md b/Sources/Glf/Glf.docc/Glf.md new file mode 100644 index 0000000000..00bacef94b --- /dev/null +++ b/Sources/Glf/Glf.docc/Glf.md @@ -0,0 +1,3 @@ +# ``Glf``: Utility classes for OpenGL + +Utility classes for OpenGL output. diff --git a/Sources/Glf/Resources/plugInfo.json b/Sources/Glf/Resources/plugInfo.json new file mode 100644 index 0000000000..f857cf32ab --- /dev/null +++ b/Sources/Glf/Resources/plugInfo.json @@ -0,0 +1,14 @@ +{ + "Plugins": [ + { + "Info": { + "ShaderResources": "shaders" + }, + "LibraryPath": "", + "Name": "Glf", + "ResourcePath": "Contents/Resources", + "Root": "../..", + "Type": "library" + } + ] +} diff --git a/Sources/OpenUSD/imaging/glf/shaders/pcfShader.glslfx b/Sources/Glf/Resources/shaders/pcfShader.glslfx similarity index 100% rename from Sources/OpenUSD/imaging/glf/shaders/pcfShader.glslfx rename to Sources/Glf/Resources/shaders/pcfShader.glslfx diff --git a/Sources/OpenUSD/imaging/glf/shaders/simpleLighting.glslfx b/Sources/Glf/Resources/shaders/simpleLighting.glslfx similarity index 100% rename from Sources/OpenUSD/imaging/glf/shaders/simpleLighting.glslfx rename to Sources/Glf/Resources/shaders/simpleLighting.glslfx diff --git a/Sources/Glf/bindingMap.cpp b/Sources/Glf/bindingMap.cpp new file mode 100644 index 0000000000..eca8e2d43c --- /dev/null +++ b/Sources/Glf/bindingMap.cpp @@ -0,0 +1,280 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +/// \file bindingMap.cpp + +#include "Garch/glApi.h" + +#include "Glf/bindingMap.h" +#include "Tf/diagnostic.h" +#include "Tf/stl.h" +#include "Tf/type.h" + +PXR_NAMESPACE_OPEN_SCOPE + +int GlfBindingMap::GetSamplerUnit(std::string const &name) +{ + return GetSamplerUnit(TfToken(name)); +} + +int GlfBindingMap::GetSamplerUnit(TfToken const &name) +{ + int samplerUnit = -1; + if (!TfMapLookup(_samplerBindings, name, &samplerUnit)) + { + // XXX error check < MAX_TEXTURE_IMAGE_UNITS + samplerUnit = _samplerBindingBaseIndex + (int)_samplerBindings.size(); + _samplerBindings[name] = samplerUnit; + } + TF_VERIFY(samplerUnit >= 0); + return samplerUnit; +} + +int GlfBindingMap::GetAttributeIndex(std::string const &name) +{ + return GetAttributeIndex(TfToken(name)); +} + +int GlfBindingMap::GetAttributeIndex(TfToken const &name) +{ + int attribIndex = -1; + if (!TfMapLookup(_attribBindings, name, &attribIndex)) + { + return -1; + } + return attribIndex; +} + +void GlfBindingMap::AssignSamplerUnitsToProgram(GLuint program) +{ + for (BindingMap::value_type const &p : _samplerBindings) + { + GLint loc = glGetUniformLocation(program, p.first.GetText()); + if (loc != -1) + { + glProgramUniform1i(program, loc, p.second); + } + } +} + +int GlfBindingMap::GetUniformBinding(std::string const &name) +{ + return GetUniformBinding(TfToken(name)); +} + +int GlfBindingMap::GetUniformBinding(TfToken const &name) +{ + int binding = -1; + if (!TfMapLookup(_uniformBindings, name, &binding)) + { + binding = _uniformBindingBaseIndex + (int)_uniformBindings.size(); + _uniformBindings[name] = binding; + } + TF_VERIFY(binding >= 0); + return binding; +} + +bool GlfBindingMap::HasUniformBinding(std::string const &name) const +{ + return HasUniformBinding(TfToken(name)); +} + +bool GlfBindingMap::HasUniformBinding(TfToken const &name) const +{ + return (_uniformBindings.find(name) != _uniformBindings.end()); +} + +void GlfBindingMap::AssignUniformBindingsToProgram(GLuint program) +{ + for (BindingMap::value_type const &p : _uniformBindings) + { + GLuint uboIndex = glGetUniformBlockIndex(program, p.first.GetText()); + if (uboIndex != GL_INVALID_INDEX) + { + glUniformBlockBinding(program, uboIndex, p.second); + } + } +} + +void GlfBindingMap::AddCustomBindings(GLuint program) +{ + _AddActiveAttributeBindings(program); + _AddActiveUniformBindings(program); + _AddActiveUniformBlockBindings(program); + + // assign uniform bindings / texture samplers + AssignUniformBindingsToProgram(program); + AssignSamplerUnitsToProgram(program); +} + +void GlfBindingMap::_AddActiveAttributeBindings(GLuint program) +{ + GLint numAttributes = 0; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes); + if (numAttributes == 0) + return; + + GLint maxNameLength = 0; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); + maxNameLength = std::max(maxNameLength, 100); + GLint size; + GLenum type; + char *name = new char[maxNameLength]; + + for (int i = 0; i < numAttributes; ++i) + { + glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name); + GLint location = glGetAttribLocation(program, name); + TfToken token(name); + + BindingMap::iterator it = _attribBindings.find(token); + if (it == _attribBindings.end()) + { + _attribBindings[token] = location; + } + else if (it->second != location) + { + TF_RUNTIME_ERROR("Inconsistent attribute binding detected."); + } + } + + delete[] name; +} + +void GlfBindingMap::_AddActiveUniformBindings(GLuint program) +{ + GLint numUniforms = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); + if (numUniforms == 0) + return; + + GLint maxNameLength = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); + GLint size; + GLenum type; + char *name = new char[maxNameLength]; + + for (int i = 0; i < numUniforms; ++i) + { + glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name); + switch (type) + { + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_1D_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_BUFFER: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_2D_RECT: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_2D_RECT: + GetSamplerUnit(name); + break; + } + } + delete[] name; +} + +void GlfBindingMap::_AddActiveUniformBlockBindings(GLuint program) +{ + GLint numUniformBlocks = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); + if (numUniformBlocks == 0) + return; + + GLint maxNameLength = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxNameLength); + char *name = new char[maxNameLength]; + + for (int i = 0; i < numUniformBlocks; ++i) + { + glGetActiveUniformBlockName(program, i, maxNameLength, NULL, name); + GetUniformBinding(name); + } + delete[] name; +} + +void GlfBindingMap::Debug() const +{ + printf("GlfBindingMap\n"); + + // sort for comparing baseline in testGlfBindingMap + std::map attribBindings, samplerBindings, uniformBindings; + for (BindingMap::value_type const &p : _attribBindings) + { + attribBindings.insert(p); + } + for (BindingMap::value_type const &p : _samplerBindings) + { + samplerBindings.insert(p); + } + for (BindingMap::value_type const &p : _uniformBindings) + { + uniformBindings.insert(p); + } + + printf(" Attribute bindings\n"); + for (BindingMap::value_type const &p : attribBindings) + { + printf(" %s : %d\n", p.first.GetText(), p.second); + } + printf(" Sampler bindings\n"); + for (BindingMap::value_type const &p : samplerBindings) + { + printf(" %s : %d\n", p.first.GetText(), p.second); + } + printf(" Uniform bindings\n"); + for (BindingMap::value_type const &p : uniformBindings) + { + printf(" %s : %d\n", p.first.GetText(), p.second); + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/contextCaps.cpp b/Sources/Glf/contextCaps.cpp new file mode 100644 index 0000000000..d2f67046f0 --- /dev/null +++ b/Sources/Glf/contextCaps.cpp @@ -0,0 +1,148 @@ +// +// Copyright 2018 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +#include "Garch/glApi.h" + +#include "Glf/contextCaps.h" + +#include "Glf/glContext.h" +#include "Glf/debugCodes.h" + +#include "Tf/diagnostic.h" +#include "Tf/envSetting.h" +#include "Tf/instantiateSingleton.h" + +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_INSTANTIATE_SINGLETON(GlfContextCaps); + +// Set defaults based on GL spec minimums +static const int _DefaultMaxArrayTextureLayers = 256; + +// Initialize members to ensure a sane starting state. +GlfContextCaps::GlfContextCaps() + : glVersion(0), coreProfile(false), maxArrayTextureLayers(_DefaultMaxArrayTextureLayers) +{ +} + +/*static*/ +void GlfContextCaps::InitInstance() +{ + // Initialize the render context caps. + // This needs to be called on a thread that has the gl context + // bound before we go wide on the cpus. + + // XXX: This should be called on + // an render context change event api. (bug #124971) + + GlfContextCaps &caps = TfSingleton::GetInstance(); + + GarchGLApiLoad(); + + caps._LoadCaps(); +} + +/*static*/ +const GlfContextCaps & +GlfContextCaps::GetInstance() +{ + GlfContextCaps &caps = TfSingleton::GetInstance(); + + if (caps.glVersion == 0) + { + TF_CODING_ERROR("GlfContextCaps has not been initialized"); + // Return the default set + } + + return caps; +} + +void GlfContextCaps::_LoadCaps() +{ + // Reset Values to reasonable defaults based of OpenGL minimums. + // So that if we early out, systems can still depend on the + // caps values being valid. + // + // _LoadCaps can also be called multiple times, so not want + // to mix and match values in the event of an early out. + glVersion = 0; + coreProfile = false; + maxArrayTextureLayers = _DefaultMaxArrayTextureLayers; + + if (!TF_VERIFY(GlfGLContext::GetCurrentGLContext()->IsValid())) + { + return; + } + + const char *glVendorStr = (const char *)glGetString(GL_VENDOR); + const char *glRendererStr = (const char *)glGetString(GL_RENDERER); + const char *glVersionStr = (const char *)glGetString(GL_VERSION); + + // GL hasn't been initialized yet. + if (glVersionStr == NULL) + return; + + const char *dot = strchr(glVersionStr, '.'); + if (TF_VERIFY((dot && dot != glVersionStr), + "Can't parse GL_VERSION %s", glVersionStr)) + { + // GL_VERSION = "4.5.0 " + // "4.1 " + // "4.1 " + int major = std::max(0, std::min(9, *(dot - 1) - '0')); + int minor = std::max(0, std::min(9, *(dot + 1) - '0')); + glVersion = major * 100 + minor * 10; + } + + if (glVersion >= 320) + { + GLint profileMask = 0; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask); + coreProfile = (profileMask & GL_CONTEXT_CORE_PROFILE_BIT); + } + + if (glVersion >= 300) + { + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers); + } + + if (TfDebug::IsEnabled(GLF_DEBUG_CONTEXT_CAPS)) + { + std::cout + << "GlfContextCaps: \n" + << " GL_VENDOR = " + << glVendorStr << "\n" + << " GL_RENDERER = " + << glRendererStr << "\n" + << " GL_VERSION = " + << glVersionStr << "\n" + << " GL version = " + << glVersion << "\n"; + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/debugCodes.cpp b/Sources/Glf/debugCodes.cpp similarity index 61% rename from Sources/OpenUSD/imaging/glf/debugCodes.cpp rename to Sources/Glf/debugCodes.cpp index 8ec41d1a16..b3516309ad 100644 --- a/Sources/OpenUSD/imaging/glf/debugCodes.cpp +++ b/Sources/Glf/debugCodes.cpp @@ -23,27 +23,25 @@ // /// \file debugCodes.cpp -#include "pxr/imaging/glf/debugCodes.h" +#include "Glf/debugCodes.h" -#include "pxr/base/tf/debug.h" -#include "pxr/base/tf/registryManager.h" +#include "Tf/debug.h" +#include "Tf/registryManager.h" PXR_NAMESPACE_OPEN_SCOPE - TF_REGISTRY_FUNCTION(TfDebug) { - TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_CONTEXT_CAPS, - "Glf report when context caps are initialized and dump contents"); - TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_ERROR_STACKTRACE, - "Glf dump stack trace on GL error"); - TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_SHADOW_TEXTURES, - "Glf logging for shadow map management"); - TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_DUMP_SHADOW_TEXTURES, - "Glf outputs shadows textures to image files"); - TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_POST_SURFACE_LIGHTING, - "Glf post surface lighting setup"); + TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_CONTEXT_CAPS, + "Glf report when context caps are initialized and dump contents"); + TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_ERROR_STACKTRACE, + "Glf dump stack trace on GL error"); + TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_SHADOW_TEXTURES, + "Glf logging for shadow map management"); + TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_DUMP_SHADOW_TEXTURES, + "Glf outputs shadows textures to image files"); + TF_DEBUG_ENVIRONMENT_SYMBOL(GLF_DEBUG_POST_SURFACE_LIGHTING, + "Glf post surface lighting setup"); } PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/Glf/diagnostic.cpp b/Sources/Glf/diagnostic.cpp new file mode 100644 index 0000000000..74e27bd691 --- /dev/null +++ b/Sources/Glf/diagnostic.cpp @@ -0,0 +1,346 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +// Diagnostic.cpp +// + +#include "Garch/glApi.h" + +#include "Glf/diagnostic.h" +#include "Glf/debugCodes.h" +#include "Glf/glContext.h" + +#include "Tf/diagnostic.h" +#include "Tf/envSetting.h" +#include "Tf/stackTrace.h" +#include "Tf/stringUtils.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_ENV_SETTING(GLF_ENABLE_DIAGNOSTIC_TRACE, 0, + "Enable glDebug* diagnostic tracing in Glf."); + +static bool +GlfTraceEnabled() +{ +#if defined(GL_KHR_debug) + static bool _v = TfGetEnvSetting(GLF_ENABLE_DIAGNOSTIC_TRACE) == 1; + return _v; +#else + return false; +#endif +} + +void GlfPostPendingGLErrors(std::string const &where) +{ + bool foundError = false; + GLenum error; + // Protect from doing infinite looping when glGetError + // is called from an invalid context. + int watchDogCount = 0; + while ((watchDogCount++ < 256) && + ((error = glGetError()) != GL_NO_ERROR)) + { + foundError = true; + const GLubyte *errorString = gluErrorString(error); + + std::ostringstream errorMessage; + if (!errorString) + { + errorMessage << "GL error code: 0x" << std::hex << error + << std::dec; + } + else + { + errorMessage << "GL error: " << errorString; + } + + if (!where.empty()) + { + errorMessage << ", reported from " << where; + } + + TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg(errorMessage.str() + "\n"); + + TF_RUNTIME_ERROR(errorMessage.str()); + } + if (foundError) + { + TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg(TfStringPrintf("==== GL Error Stack ====\n%s\n", TfGetStackTrace().c_str())); + } +} + +void GlfRegisterDefaultDebugOutputMessageCallback() +{ +#if defined(GL_KHR_debug) + if (glDebugMessageCallbackARB) + { + glDebugMessageCallbackARB( + (GLDEBUGPROCARB)GlfDefaultDebugOutputMessageCallback, 0); + // Disable push/pop group messages; we don't want to print these. + glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PUSH_GROUP, + GL_DONT_CARE, 0, nullptr, GL_FALSE); + glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP, + GL_DONT_CARE, 0, nullptr, GL_FALSE); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + } +#endif +} + +void GlfDefaultDebugOutputMessageCallback( + GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, GLchar const *message, GLvoid const *userParam) +{ +#if defined(GL_ARB_debug_output) || defined(GL_VERSION_4_3) + if (type == GL_DEBUG_TYPE_ERROR_ARB) + { + TF_RUNTIME_ERROR("GL debug output: " + "source: %s type: %s id: %d severity: %s message: %s", + GlfDebugEnumToString(source), + GlfDebugEnumToString(type), + id, + GlfDebugEnumToString(severity), + message); + + TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg(TfStringPrintf("==== GL Error Stack ====\n%s\n", TfGetStackTrace().c_str())); + } + else + { + TF_WARN("GL debug output: %s", message); + } +#endif +} + +char const * +GlfDebugEnumToString(GLenum debugEnum) +{ +#if defined(GL_ARB_debug_output) || defined(GL_VERSION_4_3) + switch (debugEnum) + { + case GL_DEBUG_SOURCE_API_ARB: + return "GL_DEBUG_SOURCE_API"; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: + return "GL_DEBUG_SOURCE_WINDOW_SYSTEM"; + case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: + return "GL_DEBUG_SOURCE_SHADER_COMPILER"; + case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: + return "GL_DEBUG_SOURCE_THIRD_PARTY"; + case GL_DEBUG_SOURCE_APPLICATION_ARB: + return "GL_DEBUG_SOURCE_APPLICATION"; + case GL_DEBUG_SOURCE_OTHER_ARB: + return "GL_DEBUG_SOURCE_OTHER"; + + case GL_DEBUG_TYPE_ERROR_ARB: + return "GL_DEBUG_TYPE_ERROR"; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: + return "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + return "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"; + case GL_DEBUG_TYPE_PORTABILITY_ARB: + return "GL_DEBUG_TYPE_PORTABILITY"; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: + return "GL_DEBUG_TYPE_PERFORMANCE"; + case GL_DEBUG_TYPE_OTHER_ARB: + return "GL_DEBUG_TYPE_OTHER"; +#if defined(GL_VERSION_4_3) + case GL_DEBUG_TYPE_MARKER: + return "GL_DEBUG_TYPE_MARKER"; + case GL_DEBUG_TYPE_PUSH_GROUP: + return "GL_DEBUG_TYPE_PUSH_GROUP"; + case GL_DEBUG_TYPE_POP_GROUP: + return "GL_DEBUG_TYPE_POP_GROUP"; +#endif + +#if defined(GL_VERSION_4_3) + case GL_DEBUG_SEVERITY_NOTIFICATION: + return "GL_DEBUG_SEVERITY_NOTIFICATION"; +#endif + case GL_DEBUG_SEVERITY_HIGH_ARB: + return "GL_DEBUG_SEVERITY_HIGH"; + case GL_DEBUG_SEVERITY_MEDIUM_ARB: + return "GL_DEBUG_SEVERITY_MEDIUM"; + case GL_DEBUG_SEVERITY_LOW_ARB: + return "GL_DEBUG_SEVERITY_LOW"; + } +#endif + TF_CODING_ERROR("unknown debug enum"); + return "unknown"; +} + +static void +_GlfPushDebugGroup(char const *message) +{ +#if defined(GL_KHR_debug) + if (GARCH_GLAPI_HAS(KHR_debug)) + { + glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 0, -1, message); + } +#endif +} + +static void +_GlfPopDebugGroup() +{ +#if defined(GL_KHR_debug) + if (GARCH_GLAPI_HAS(KHR_debug)) + { + glPopDebugGroup(); + } +#endif +} + +GlfDebugGroup::GlfDebugGroup(char const *message) +{ + if (GlfTraceEnabled()) + { + _GlfPushDebugGroup(message); + } +} + +GlfDebugGroup::~GlfDebugGroup() +{ + if (GlfTraceEnabled()) + { + _GlfPopDebugGroup(); + } +} + +void GlfDebugLabelBuffer(GLuint id, char const *label) +{ +#if defined(GL_KHR_debug) + if (GlfTraceEnabled()) + { + if (GARCH_GLAPI_HAS(KHR_debug)) + { + glObjectLabel(GL_BUFFER, id, -1, label); + } + } +#endif +} + +void GlfDebugLabelShader(GLuint id, char const *label) +{ +#if defined(GL_KHR_debug) + if (GlfTraceEnabled()) + { + if (GARCH_GLAPI_HAS(KHR_debug)) + { + glObjectLabel(GL_SHADER, id, -1, label); + } + } +#endif +} + +void GlfDebugLabelProgram(GLuint id, char const *label) +{ +#if defined(GL_KHR_debug) + if (GlfTraceEnabled()) + { + if (GARCH_GLAPI_HAS(KHR_debug)) + { + glObjectLabel(GL_PROGRAM, id, -1, label); + } + } +#endif +} + +GlfGLQueryObject::GlfGLQueryObject() + : _id(0), _target(0) +{ + GarchGLApiLoad(); + if (glGenQueries) + { + glGenQueries(1, &_id); + } +} + +GlfGLQueryObject::~GlfGLQueryObject() +{ + GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; + if (glDeleteQueries && _id) + { + glDeleteQueries(1, &_id); + } +} + +void GlfGLQueryObject::BeginSamplesPassed() +{ + Begin(GL_SAMPLES_PASSED); +} + +void GlfGLQueryObject::BeginPrimitivesGenerated() +{ + Begin(GL_PRIMITIVES_GENERATED); +} +void GlfGLQueryObject::BeginTimeElapsed() +{ + Begin(GL_TIME_ELAPSED); +} + +void GlfGLQueryObject::Begin(GLenum target) +{ + _target = target; + if (glBeginQuery && _id) + { + glBeginQuery(_target, _id); + } +} + +void GlfGLQueryObject::End() +{ + if (glEndQuery && _target) + { + glEndQuery(_target); + } + _target = 0; +} + +GLint64 +GlfGLQueryObject::GetResult() +{ + GLint64 value = 0; + if (glGetQueryObjecti64v && _id) + { + glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &value); + } + return value; +} + +GLint64 +GlfGLQueryObject::GetResultNoWait() +{ + GLint64 value = 0; + if (glGetQueryObjecti64v && _id) + { + glGetQueryObjecti64v(_id, GL_QUERY_RESULT_AVAILABLE, &value); + if (value == GL_TRUE) + { + glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &value); + } + } + return value; +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/drawTarget.cpp b/Sources/Glf/drawTarget.cpp new file mode 100644 index 0000000000..9ae4e1168d --- /dev/null +++ b/Sources/Glf/drawTarget.cpp @@ -0,0 +1,855 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +// glf/drawTarget.cpp +// + +#include "Garch/glApi.h" + +#include "Glf/drawTarget.h" +#include "Glf/glContext.h" +#include "Glf/diagnostic.h" +#include "Hio/image.h" +#include "Glf/utils.h" + +#include "Hf/perfLog.h" + +#include "Tf/stringUtils.h" +#include "Tf/envSetting.h" + +#include "Trace/traceImpl.h" + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_ENV_SETTING(GLF_DRAW_TARGETS_NUM_SAMPLES, 4, + "Number of samples greater than 1 forces MSAA."); + +static unsigned int +GetNumSamples() +{ + static int reqNumSamples = TfGetEnvSetting(GLF_DRAW_TARGETS_NUM_SAMPLES); + unsigned int numSamples = 1; + if (reqNumSamples > 1) + { + numSamples = (reqNumSamples & (reqNumSamples - 1)) ? 1 : reqNumSamples; + } + return numSamples; +} + +GlfDrawTargetRefPtr +GlfDrawTarget::New(GfVec2i const &size, bool requestMSAA) +{ + return TfCreateRefPtr(new This(size, requestMSAA)); +} + +GlfDrawTarget::GlfDrawTarget(GfVec2i const &size, bool requestMSAA /* =false */) : _framebuffer(0), + _framebufferMS(0), + _unbindRestoreReadFB(0), + _unbindRestoreDrawFB(0), + _bindDepth(0), + _size(size), + _numSamples(1) +{ + GarchGLApiLoad(); + + // If MSAA has been requested and it is enabled then we will create + // msaa buffers + if (requestMSAA) + { + _numSamples = GetNumSamples(); + } + + _GenFrameBuffer(); + + _attachmentsPtr = TfCreateRefPtr(new AttachmentsContainer); +} + +GlfDrawTargetRefPtr +GlfDrawTarget::New(GlfDrawTargetPtr const &drawtarget) +{ + return TfCreateRefPtr(new This(drawtarget)); +} + +// clone constructor : generates a new GL framebuffer, but share the texture +// attachments. +GlfDrawTarget::GlfDrawTarget(GlfDrawTargetPtr const &drawtarget) : _framebuffer(0), + _framebufferMS(0), + _unbindRestoreReadFB(0), + _unbindRestoreDrawFB(0), + _bindDepth(0), + _size(drawtarget->_size), + _numSamples(drawtarget->_numSamples), + _owningContext() +{ + GarchGLApiLoad(); + + _GenFrameBuffer(); + + // share the RefPtr to the map of attachments + _attachmentsPtr = drawtarget->_attachmentsPtr; + + Bind(); + + // attach the textures to the correct framebuffer mount points + for (AttachmentsMap::value_type const &p : _attachmentsPtr->attachments) + { + _BindAttachment(p.second); + } + + Unbind(); +} + +GlfDrawTarget::~GlfDrawTarget() +{ + // If the owning context has died, there's nothing to free. + if (!_owningContext->IsValid()) + { + return; + } + + // bind the owning context to make sure we delete frame buffer on correct + // context. + GlfGLContextScopeHolder contextHolder(_owningContext); + + _DeleteAttachments(); + + if (_framebuffer) + { + TF_VERIFY(glIsFramebuffer(_framebuffer), + "Tried to free invalid framebuffer"); + + glDeleteFramebuffers(1, &_framebuffer); + _framebuffer = 0; + } + + if (_framebufferMS) + { + TF_VERIFY(glIsFramebuffer(_framebufferMS), + "Tried to free invalid multisampled framebuffer"); + + glDeleteFramebuffers(1, &_framebufferMS); + _framebufferMS = 0; + } +} + +void GlfDrawTarget::AddAttachment(std::string const &name, + GLenum format, GLenum type, + GLenum internalFormat) +{ + if (!IsBound()) + { + TF_CODING_ERROR("Cannot change the size of an unbound GlfDrawTarget"); + } + + AttachmentsMap &attachments = _GetAttachments(); + AttachmentsMap::iterator it = attachments.find(name); + + if (it == attachments.end()) + { + + AttachmentRefPtr attachment = Attachment::New((int)attachments.size(), + format, type, + internalFormat, _size, + _numSamples); + + attachments.insert(AttachmentsMap::value_type(name, attachment)); + + TF_VERIFY(attachment->GetGlTextureName() > 0, + "Attachment \"%s\" was not added " + "and cannot be bound in MatDisplayMaterial", + name.c_str()); + + _BindAttachment(attachment); + } + else + { + TF_CODING_ERROR("Attachment \"" + name + "\" already exists for this " + "DrawTarget"); + } +} + +void GlfDrawTarget::DeleteAttachment(std::string const &name) +{ + AttachmentsMap &attachments = _GetAttachments(); + AttachmentsMap::iterator it = attachments.find(name); + + if (it != attachments.end()) + { + attachments.erase(it); + } + else + { + TF_CODING_ERROR("Attachment \"" + name + "\" does not exist for this " + "DrawTarget"); + } +} + +GlfDrawTarget::AttachmentRefPtr +GlfDrawTarget::GetAttachment(std::string const &name) +{ + AttachmentsMap &attachments = _GetAttachments(); + AttachmentsMap::iterator it = attachments.find(name); + + if (it != attachments.end()) + { + return it->second; + } + else + { + return TfNullPtr; + } +} + +void GlfDrawTarget::ClearAttachments() +{ + _DeleteAttachments(); +} + +void GlfDrawTarget::CloneAttachments(GlfDrawTargetPtr const &drawtarget) +{ + if (!drawtarget) + { + TF_CODING_ERROR("Cannot clone TfNullPtr attachments."); + } + + // garbage collection will take care of the existing instance pointed to + // by the RefPtr + _attachmentsPtr = drawtarget->_attachmentsPtr; + + for (AttachmentsMap::value_type const &p : _attachmentsPtr->attachments) + { + _BindAttachment(p.second); + } +} + +GlfDrawTarget::AttachmentsMap const & +GlfDrawTarget::GetAttachments() const +{ + return _GetAttachments(); +} + +GlfDrawTarget::AttachmentsMap & +GlfDrawTarget::_GetAttachments() const +{ + TF_VERIFY(_attachmentsPtr, + "DrawTarget has uninitialized attachments map."); + + return _attachmentsPtr->attachments; +} + +void GlfDrawTarget::SetSize(GfVec2i size) +{ + if (size == _size) + { + return; + } + + if (!IsBound()) + { + TF_CODING_ERROR("Cannot change the size of an unbound DrawTarget"); + } + + _size = size; + + AttachmentsMap &attachments = _GetAttachments(); + + for (AttachmentsMap::value_type const &p : attachments) + { + AttachmentRefPtr var = p.second; + + var->ResizeTexture(_size); + + _BindAttachment(var); + } +} + +void GlfDrawTarget::_DeleteAttachments() +{ + // Can't delete the attachment textures while someone else is still holding + // onto them. + // XXX This code needs refactoring so that Attachment & AttachmentsContainer + // own the methods over their data (with casccading calls coming from the + // DrawTarget API). Checking for the RefPtr uniqueness is somewhat working + // against the nature of RefPtr.. + if (!_attachmentsPtr->IsUnique()) + { + return; + } + + AttachmentsMap &attachments = _GetAttachments(); + + attachments.clear(); +} + +static int _GetMaxAttachments() +{ + int maxAttach = 0; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxAttach); + return maxAttach; +} + +void GlfDrawTarget::_GenFrameBuffer() +{ + _SaveBindingState(); + + _owningContext = GlfGLContext::GetCurrentGLContext(); + + // Create multisampled framebuffer + if (HasMSAA()) + { + glGenFramebuffers(1, &_framebufferMS); + glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); + TF_VERIFY(glIsFramebuffer(_framebufferMS), + "Failed to allocate multisampled framebuffer"); + } + + // Create non-multisampled framebuffer + glGenFramebuffers(1, &_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + TF_VERIFY(glIsFramebuffer(_framebuffer), + "Failed to allocate framebuffer"); + + _RestoreBindingState(); +} + +GLuint +GlfDrawTarget::GetFramebufferId() const +{ + return _framebuffer; +} + +GLuint +GlfDrawTarget::GetFramebufferMSId() const +{ + return _framebufferMS; +} + +// Attach a texture to one of the attachment points of the framebuffer. +// We assume that the framebuffer is currently bound ! +void GlfDrawTarget::_BindAttachment(GlfDrawTarget::AttachmentRefPtr const &a) +{ + GLuint id = a->GetGlTextureName(); + GLuint idMS = a->GetGlTextureMSName(); + + int attach = a->GetAttach(); + + GLenum attachment = GL_COLOR_ATTACHMENT0; + if (a->GetFormat() == GL_DEPTH_COMPONENT) + { + attachment = GL_DEPTH_ATTACHMENT; + } + else if (a->GetFormat() == GL_DEPTH_STENCIL) + { + attachment = GL_DEPTH_STENCIL_ATTACHMENT; + } + else + { + if (attach < 0) + { + TF_CODING_ERROR("Attachment index cannot be negative"); + return; + } + + TF_VERIFY(attach < _GetMaxAttachments(), + "Exceeding number of Attachments available "); + + attachment += attach; + } + + GLint restoreFramebuffer = 0; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &restoreFramebuffer); + + // Multisampled framebuffer + if (HasMSAA()) + { + glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); + glFramebufferTexture2D(GL_FRAMEBUFFER, + attachment, GL_TEXTURE_2D_MULTISAMPLE, idMS, /*level*/ 0); + } + + // Regular framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, + attachment, GL_TEXTURE_2D, id, /*level*/ 0); + + glBindFramebuffer(GL_FRAMEBUFFER, restoreFramebuffer); + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfDrawTarget::_SaveBindingState() +{ + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, + (GLint *)&_unbindRestoreReadFB); + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, + (GLint *)&_unbindRestoreDrawFB); +} + +void GlfDrawTarget::_RestoreBindingState() +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, + _unbindRestoreReadFB); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, + _unbindRestoreDrawFB); +} + +void GlfDrawTarget::Bind() +{ + if (++_bindDepth != 1) + { + return; + } + + GLF_GROUP_FUNCTION(); + + _SaveBindingState(); + + // GL Frame buffer objects are not shared between + // contexts, So make sure we are on our owning context before we try to + // bind. The reason to test rather than switch is because the user's + // code may have setup other gl state and not expect a context switch here. + // Also the switch may be expensive, so we want to be explict about when + // they can occur. + if (!TF_VERIFY(_owningContext->IsCurrent())) + { + return; + } + + if (HasMSAA()) + { + glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + } + + GLF_POST_PENDING_GL_ERRORS(); +} + +bool GlfDrawTarget::IsBound() const +{ + return (_bindDepth > 0); +} + +void GlfDrawTarget::Unbind() +{ + if (--_bindDepth != 0) + { + return; + } + GLF_GROUP_FUNCTION(); + + _RestoreBindingState(); + + TouchContents(); + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfDrawTarget::_Resolve() +{ + // Resolve MSAA fbo to a regular fbo + glBindFramebuffer(GL_READ_FRAMEBUFFER, _framebufferMS); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _framebuffer); + glBlitFramebuffer(0, 0, _size[0], _size[1], + 0, 0, _size[0], _size[1], + GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT, + GL_NEAREST); +} + +void GlfDrawTarget::Resolve() +{ + GLF_GROUP_FUNCTION(); + + if (HasMSAA()) + { + _SaveBindingState(); + _Resolve(); + _RestoreBindingState(); + } +} + +/* static */ +void GlfDrawTarget::Resolve(const std::vector &drawTargets) +{ + GLF_GROUP_FUNCTION(); + + bool anyResolved = false; + + for (GlfDrawTarget *dt : drawTargets) + { + if (dt->HasMSAA()) + { + if (!anyResolved) + { + // If this is the first draw target to be resolved, + // save the old binding state. + anyResolved = true; + drawTargets[0]->_SaveBindingState(); + } + dt->_Resolve(); + } + } + + if (anyResolved) + { + // If any draw targets were resolved, restore the old binding state. + drawTargets[0]->_RestoreBindingState(); + } +} + +void GlfDrawTarget::TouchContents() +{ + AttachmentsMap const &attachments = GetAttachments(); + + for (AttachmentsMap::value_type const &p : attachments) + { + p.second->TouchContents(); + } +} + +bool GlfDrawTarget::IsValid(std::string *reason) +{ + return _Validate(reason); +} + +bool GlfDrawTarget::_Validate(std::string *reason) +{ + if (!_framebuffer) + { + return false; + } + + return GlfCheckGLFrameBufferStatus(GL_FRAMEBUFFER, reason); +} + +bool GlfDrawTarget::WriteToFile(std::string const &name, + std::string const &filename, + GfMatrix4d const &viewMatrix, + GfMatrix4d const &projectionMatrix) +{ + TRACE_FUNCTION(); + + AttachmentsMap const &attachments = GetAttachments(); + AttachmentsMap::const_iterator it = attachments.find(name); + + if (it == attachments.end()) + { + TF_CODING_ERROR("\"" + name + "\" is not a valid variable name for this" + " DrawTarget"); + return false; + } + + AttachmentRefPtr const &a = it->second; + + if (!_framebuffer) + { + TF_CODING_ERROR("DrawTarget has no framebuffer"); + return false; + } + + int nelems = GlfGetNumElements(a->GetFormat()), + elemsize = GlfGetElementSize(a->GetType()), + stride = _size[0] * nelems * elemsize, + bufsize = _size[1] * stride; + + std::unique_ptr buf(new char[bufsize]); + + { + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + + GLint restoreBinding, restoreActiveTexture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &restoreBinding); + glGetIntegerv(GL_ACTIVE_TEXTURE, &restoreActiveTexture); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, a->GetGlTextureName()); + + { + TRACE_FUNCTION_SCOPE("glGetTexImage"); + glGetTexImage(GL_TEXTURE_2D, 0, a->GetFormat(), a->GetType(), + buf.get()); + } + + glActiveTexture(restoreActiveTexture); + glBindTexture(GL_TEXTURE_2D, restoreBinding); + + glPopClientAttrib(); + } + + VtDictionary metadata; + + std::string ext = TfStringGetSuffix(filename); + if (name == "depth" && ext == "zfile") + { + // transform depth value from normalized to camera space length + float *p = (float *)buf.get(); + for (size_t i = 0; i < bufsize / sizeof(float); ++i) + { + p[i] = (float)(-2 * p[i] / projectionMatrix[2][2]); + } + + // embed matrices into metadata + GfMatrix4d worldToCameraTransform = viewMatrix; + GfMatrix4d worldToScreenTransform = viewMatrix * projectionMatrix; + + GfMatrix4d invZ = GfMatrix4d().SetScale(GfVec3d(1, 1, -1)); + worldToCameraTransform *= invZ; + + metadata["Nl"] = worldToCameraTransform; + metadata["NP"] = worldToScreenTransform; + } + + GLenum glInternalFormat = a->GetInternalFormat(); + bool isSRGB = (glInternalFormat == GL_SRGB8 || + glInternalFormat == GL_SRGB8_ALPHA8); + HioImage::StorageSpec storage; + storage.width = _size[0]; + storage.height = _size[1]; + storage.format = GlfGetHioFormat(a->GetFormat(), + a->GetType(), + /* isSRGB */ isSRGB); + storage.flipped = true; + storage.data = buf.get(); + + { + TRACE_FUNCTION_SCOPE("writing image"); + + HioImageSharedPtr const image = HioImage::OpenForWriting(filename); + const bool writeSuccess = image && image->Write(storage, metadata); + + if (!writeSuccess) + { + TF_RUNTIME_ERROR("Failed to write image to %s", filename.c_str()); + return false; + } + } + + GLF_POST_PENDING_GL_ERRORS(); + + return true; +} + +//---------------------------------------------------------------------- + +GlfDrawTarget::AttachmentRefPtr +GlfDrawTarget::Attachment::New(int glIndex, GLenum format, GLenum type, + GLenum internalFormat, GfVec2i size, + unsigned int numSamples) +{ + return TfCreateRefPtr(new Attachment(glIndex, format, type, + internalFormat, size, + numSamples)); +} + +GlfDrawTarget::Attachment::Attachment(int glIndex, GLenum format, + GLenum type, GLenum internalFormat, + GfVec2i size, + unsigned int numSamples) : _textureName(0), + _textureNameMS(0), + _format(format), + _type(type), + _internalFormat(internalFormat), + _glIndex(glIndex), + _size(size), + _numSamples(numSamples) +{ + _GenTexture(); +} + +GlfDrawTarget::Attachment::~Attachment() +{ + _DeleteTexture(); +} + +// Generate a simple GL_TEXTURE_2D to use as an attachment +// we assume that the framebuffer is currently bound ! +void GlfDrawTarget::Attachment::_GenTexture() +{ + HF_MALLOC_TAG_FUNCTION(); + + GLenum internalFormat = _internalFormat; + GLenum type = _type; + size_t memoryUsed = 0; + + if (_format == GL_DEPTH_COMPONENT) + { + internalFormat = GL_DEPTH_COMPONENT32F; + if (type != GL_FLOAT) + { + TF_CODING_ERROR("Only GL_FLOAT textures can be used for the" + " depth attachment point"); + type = GL_FLOAT; + } + } + + int bytePerPixel = (_type == GL_FLOAT) ? 4 : 1; + int numChannel; + switch (_format) + { + case GL_RG: + numChannel = 2; + break; + + case GL_RGB: + numChannel = 3; + break; + + case GL_RGBA: + numChannel = 4; + break; + + default: + numChannel = 1; + } + + size_t baseImageSize = (size_t)(bytePerPixel * + numChannel * + _size[0] * + _size[1]); + + // Create multisampled texture + if (_numSamples > 1) + { + glGenTextures(1, &_textureNameMS); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _textureNameMS); + + // XXX: Hardcoded filtering for now + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, + _numSamples, _internalFormat, + _size[0], _size[1], GL_TRUE); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); + + memoryUsed = baseImageSize * _numSamples; + } + + // Create non-multisampled texture + glGenTextures(1, &_textureName); + glBindTexture(GL_TEXTURE_2D, _textureName); + + // XXX: Hardcoded filtering for now + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, /*level*/ 0, internalFormat, + _size[0], _size[1], + /*border*/ 0, _format, type, NULL); + + glBindTexture(GL_TEXTURE_2D, 0); + + memoryUsed += baseImageSize; + + _SetMemoryUsed(memoryUsed); + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfDrawTarget::Attachment::_DeleteTexture() +{ + if (_textureName) + { + GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; + + TF_VERIFY(glIsTexture(_textureName), "Tried to delete an invalid texture"); + glDeleteTextures(1, &_textureName); + _textureName = 0; + } + + if (_textureNameMS) + { + GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; + + TF_VERIFY(glIsTexture(_textureNameMS), "Tried to delete an invalid texture"); + glDeleteTextures(1, &_textureNameMS); + _textureNameMS = 0; + } + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfDrawTarget::Attachment::ResizeTexture(const GfVec2i &size) +{ + _size = size; + + _DeleteTexture(); + _GenTexture(); +} + +/* virtual */ +GlfTexture::BindingVector +GlfDrawTarget::Attachment::GetBindings(TfToken const &identifier, + GLuint samplerName) +{ + return BindingVector(1, + Binding(identifier, GlfTextureTokens->texels, + GL_TEXTURE_2D, GetGlTextureName(), samplerName)); +} + +GLuint +GlfDrawTarget::Attachment::GetGlTextureName() +{ + return _textureName; +} + +/* virtual */ +VtDictionary +GlfDrawTarget::Attachment::GetTextureInfo(bool forceLoad) +{ + TF_UNUSED(forceLoad); + + VtDictionary info; + + info["width"] = (int)_size[0]; + info["height"] = (int)_size[1]; + info["memoryUsed"] = GetMemoryUsed(); + info["depth"] = 1; + info["format"] = (int)_internalFormat; + info["imageFilePath"] = TfToken("DrawTarget"); + info["referenceCount"] = GetCurrentCount(); + info["numSamples"] = _numSamples; + + return info; +} + +void GlfDrawTarget::Attachment::TouchContents() +{ + _UpdateContentsID(); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/glContext.cpp b/Sources/Glf/glContext.cpp new file mode 100644 index 0000000000..b0df274728 --- /dev/null +++ b/Sources/Glf/glContext.cpp @@ -0,0 +1,146 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "Glf/glContext.h" +#include "Glf/glContextRegistry.h" +#include "Garch/glPlatformContext.h" + +#include "Trace/traceImpl.h" + +PXR_NAMESPACE_OPEN_SCOPE + +// +// GlfGLContext +// + +GlfGLContext::GlfGLContext() +{ + // Do nothing +} + +GlfGLContext::~GlfGLContext() +{ + GlfGLContextRegistry::GetInstance().Remove(this); +} + +GlfGLContextSharedPtr +GlfGLContext::GetCurrentGLContext() +{ + return GlfGLContextRegistry::GetInstance().GetCurrent(); +} + +GlfGLContextSharedPtr +GlfGLContext::GetSharedGLContext() +{ + return GlfGLContextRegistry::GetInstance().GetShared(); +} + +void GlfGLContext::MakeCurrent(const GlfGLContextSharedPtr &context) +{ + TRACE_FUNCTION(); + + if (context && context->IsValid()) + { + context->_MakeCurrent(); + + // Now that this context is current add it to the registry for + // later lookup. + GlfGLContextRegistry::GetInstance().DidMakeCurrent(context); + } + else + { + DoneCurrent(); + } +} + +bool GlfGLContext::AreSharing(GlfGLContextSharedPtr const &context1, + GlfGLContextSharedPtr const &context2) +{ + return (context1 && context1->IsSharing(context2)); +} + +bool GlfGLContext::IsInitialized() +{ + return GlfGLContextRegistry::GetInstance().IsInitialized(); +} + +bool GlfGLContext::IsCurrent() const +{ + return IsValid() && _IsEqual(GetCurrentGLContext()); +} + +void GlfGLContext::MakeCurrent() +{ + if (IsValid()) + { + _MakeCurrent(); + } +} + +void GlfGLContext::DoneCurrent() +{ + GarchGLPlatformContextState::DoneCurrent(); +} + +bool GlfGLContext::IsSharing(GlfGLContextSharedPtr const &otherContext) +{ + return otherContext && IsValid() && + otherContext->IsValid() && _IsSharing(otherContext); +} + +// +// GlfGLContextScopeHolder +// + +GlfGLContextScopeHolder::GlfGLContextScopeHolder( + const GlfGLContextSharedPtr &newContext) : _newContext(newContext) +{ + if (_newContext) + { + _oldContext = GlfGLContext::GetCurrentGLContext(); + } + _MakeNewContextCurrent(); +} + +GlfGLContextScopeHolder::~GlfGLContextScopeHolder() +{ + _RestoreOldContext(); +} + +void GlfGLContextScopeHolder::_MakeNewContextCurrent() +{ + if (_newContext) + { + GlfGLContext::MakeCurrent(_newContext); + } +} + +void GlfGLContextScopeHolder::_RestoreOldContext() +{ + if (_newContext) + { + GlfGLContext::MakeCurrent(_oldContext); + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/glContextRegistry.cpp b/Sources/Glf/glContextRegistry.cpp new file mode 100644 index 0000000000..16eed0f8f4 --- /dev/null +++ b/Sources/Glf/glContextRegistry.cpp @@ -0,0 +1,208 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +/// \file glContextRegistry.cpp + +#include "Glf/glContextRegistry.h" +#include "Glf/glRawContext.h" +#include "Garch/glPlatformContext.h" +#include "Tf/diagnostic.h" +#include "Tf/instantiateSingleton.h" +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +typedef std::weak_ptr GlfGLContextWeakPtr; + +static GlfGLContextSharedPtr _nullContext; + +TF_INSTANTIATE_SINGLETON(GlfGLContextRegistry); + +// +// GlfGLContextRegistry_Data +// + +struct GlfGLContextRegistry_Data +{ + typedef std::unordered_map + ContextsByState; + typedef std::map + StatesByContext; + + ContextsByState contextsByState; + StatesByContext statesByContext; +}; + +// +// GlfGLContextRegistry +// + +GlfGLContextRegistry::GlfGLContextRegistry() : _sharedContextInitialized(false), + _data(new GlfGLContextRegistry_Data) +{ + // Make a context for when no context is bound. This is to avoid + // repeatedly creating a raw context for this condition in GetCurrent(). + GarchGLPlatformContextState nullState = GarchGetNullGLPlatformContextState(); + _nullContext = GlfGLRawContext::New(nullState); + _data->contextsByState[nullState] = _nullContext; + _data->statesByContext[_nullContext.get()] = nullState; +} + +GlfGLContextRegistry::~GlfGLContextRegistry() +{ + _nullContext.reset(); +} + +bool GlfGLContextRegistry::IsInitialized() const +{ + return !_interfaces.empty(); +} + +void GlfGLContextRegistry::Add(GlfGLContextRegistrationInterface *iface) +{ + if (TF_VERIFY(iface, "NULL GlfGLContextRegistrationInterface")) + { + _interfaces.emplace_back(iface); + } +} + +GlfGLContextSharedPtr +GlfGLContextRegistry::GetShared() +{ + if (!_sharedContextInitialized) + { + + // Don't do this again. + _sharedContextInitialized = true; + + _shared = GlfGLContextSharedPtr(); + + // Find the first interface with a shared context. + for (std::unique_ptr &iface : + _interfaces) + { + if (GlfGLContextSharedPtr shared = iface->GetShared()) + { + _shared = shared; + return _shared; + } + } + + TF_CODING_ERROR("No shared context registered."); + } + return _shared; +} + +GlfGLContextSharedPtr +GlfGLContextRegistry::GetCurrent() +{ + // Get the current raw state. + GarchGLPlatformContextState rawState; + + // See if we know a context with this raw state. + GlfGLContextRegistry_Data::ContextsByState::iterator i = + _data->contextsByState.find(rawState); + if (i != _data->contextsByState.end()) + { + // Promote weak to shared. + return GlfGLContextSharedPtr(i->second); + } + + // We don't know this raw state. Try syncing each interface to see + // if any system thinks this state is current. + for (std::unique_ptr &iface : _interfaces) + { + if (GlfGLContextSharedPtr currentContext = iface->GetCurrent()) + { + if (currentContext->IsValid()) + { + GlfGLContext::MakeCurrent(currentContext); + GarchGLPlatformContextState currentRawState; + if (rawState == currentRawState) + { + // Yes, currentContext has the raw state we're looking + // for. GlfGLContext::MakeCurrent() has already called + // DidMakeCurrent() so this context is now registered + // in case we need to look it up again. + return currentContext; + } + } + } + } + + // We can't find this state. We'll return the raw context as a fallback. + // Note that the raw context's IsValid() will not go false when the + // context is destroyed. This is why we prefer a non-raw state. + rawState.MakeCurrent(); + return GlfGLRawContext::New(rawState); +} + +void GlfGLContextRegistry::DidMakeCurrent(const GlfGLContextSharedPtr &context) +{ + // If we already know about this context then do nothing. If we don't + // but we already know about this state then still do nothing. + if (_data->statesByContext.find(context.get()) == + _data->statesByContext.end()) + { + GarchGLPlatformContextState currentState; + if (_data->contextsByState.find(currentState) == + _data->contextsByState.end()) + { + // Register context under the current context state. + _data->contextsByState[currentState] = context; + _data->statesByContext[context.get()] = currentState; + } + } +} + +void GlfGLContextRegistry::Remove(const GlfGLContext *context) +{ + GlfGLContextRegistry_Data::StatesByContext::iterator i = + _data->statesByContext.find(context); + if (i != _data->statesByContext.end()) + { + TF_VERIFY(_data->contextsByState.erase(i->second)); + _data->statesByContext.erase(i); + } +} + +// +// GlfGLContextRegistrationInterface +// + +GlfGLContextRegistrationInterface::GlfGLContextRegistrationInterface() +{ + // Register ourself. + GlfGLContextRegistry::GetInstance().Add(this); +} + +GlfGLContextRegistrationInterface::~GlfGLContextRegistrationInterface() +{ + // Do nothing +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/glRawContext.cpp b/Sources/Glf/glRawContext.cpp similarity index 63% rename from Sources/OpenUSD/imaging/glf/glRawContext.cpp rename to Sources/Glf/glRawContext.cpp index dbe77e05dc..12dd8aba3e 100644 --- a/Sources/OpenUSD/imaging/glf/glRawContext.cpp +++ b/Sources/Glf/glRawContext.cpp @@ -23,11 +23,10 @@ // /// \file glRawContext.cpp -#include "pxr/imaging/glf/glRawContext.h" +#include "Glf/glRawContext.h" PXR_NAMESPACE_OPEN_SCOPE - // // GlfGLRawContext // @@ -35,54 +34,49 @@ PXR_NAMESPACE_OPEN_SCOPE GlfGLRawContextSharedPtr GlfGLRawContext::New() { - return GlfGLRawContextSharedPtr( - new GlfGLRawContext(GarchGLPlatformContextState())); + return GlfGLRawContextSharedPtr( + new GlfGLRawContext(GarchGLPlatformContextState())); } GlfGLRawContextSharedPtr -GlfGLRawContext::New(const GarchGLPlatformContextState& state) +GlfGLRawContext::New(const GarchGLPlatformContextState &state) { - return GlfGLRawContextSharedPtr(new GlfGLRawContext(state)); + return GlfGLRawContextSharedPtr(new GlfGLRawContext(state)); } -GlfGLRawContext::GlfGLRawContext(const GarchGLPlatformContextState& state) : - _state(state) +GlfGLRawContext::GlfGLRawContext(const GarchGLPlatformContextState &state) : _state(state) { - // Do nothing + // Do nothing } GlfGLRawContext::~GlfGLRawContext() { - // Do nothing + // Do nothing } -bool -GlfGLRawContext::IsValid() const +bool GlfGLRawContext::IsValid() const { - return _state.IsValid(); + return _state.IsValid(); } -void -GlfGLRawContext::_MakeCurrent() +void GlfGLRawContext::_MakeCurrent() { - _state.MakeCurrent(); + _state.MakeCurrent(); } -bool -GlfGLRawContext::_IsSharing(const GlfGLContextSharedPtr& rhs) const +bool GlfGLRawContext::_IsSharing(const GlfGLContextSharedPtr &rhs) const { - return false; + return false; } -bool -GlfGLRawContext::_IsEqual(const GlfGLContextSharedPtr& rhs) const +bool GlfGLRawContext::_IsEqual(const GlfGLContextSharedPtr &rhs) const { - if (const GlfGLRawContext* rhsRaw = - dynamic_cast(rhs.get())) { - return _state == rhsRaw->_state; - } - return false; + if (const GlfGLRawContext *rhsRaw = + dynamic_cast(rhs.get())) + { + return _state == rhsRaw->_state; + } + return false; } PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/Glf/include/Glf/Glf.h b/Sources/Glf/include/Glf/Glf.h new file mode 100644 index 0000000000..248dc9d1ef --- /dev/null +++ b/Sources/Glf/include/Glf/Glf.h @@ -0,0 +1,24 @@ +#ifndef __PXR_IMAGING_GLF_H__ +#define __PXR_IMAGING_GLF_H__ + +// glf +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // __PXR_IMAGING_GLF_H__ diff --git a/Sources/OpenUSD/include/imaging/glf/api.h b/Sources/Glf/include/Glf/api.h similarity index 65% rename from Sources/OpenUSD/include/imaging/glf/api.h rename to Sources/Glf/include/Glf/api.h index f64254b624..a903c29d9e 100644 --- a/Sources/OpenUSD/include/imaging/glf/api.h +++ b/Sources/Glf/include/Glf/api.h @@ -24,24 +24,24 @@ #ifndef PXR_IMAGING_GLF_API_H #define PXR_IMAGING_GLF_API_H -#include "pxr/base/arch/export.h" +#include "Arch/export.h" #if defined(PXR_STATIC) -# define GLF_API -# define GLF_API_TEMPLATE_CLASS(...) -# define GLF_API_TEMPLATE_STRUCT(...) -# define GLF_LOCAL +#define GLF_API +#define GLF_API_TEMPLATE_CLASS(...) +#define GLF_API_TEMPLATE_STRUCT(...) +#define GLF_LOCAL #else -# if defined(GLF_EXPORTS) -# define GLF_API ARCH_EXPORT -# define GLF_API_TEMPLATE_CLASS(...) ARCH_EXPORT_TEMPLATE(class, __VA_ARGS__) -# define GLF_API_TEMPLATE_STRUCT(...) ARCH_EXPORT_TEMPLATE(struct, __VA_ARGS__) -# else -# define GLF_API ARCH_IMPORT -# define GLF_API_TEMPLATE_CLASS(...) ARCH_IMPORT_TEMPLATE(class, __VA_ARGS__) -# define GLF_API_TEMPLATE_STRUCT(...) ARCH_IMPORT_TEMPLATE(struct, __VA_ARGS__) -# endif -# define GLF_LOCAL ARCH_HIDDEN +#if defined(GLF_EXPORTS) +#define GLF_API ARCH_EXPORT +#define GLF_API_TEMPLATE_CLASS(...) ARCH_EXPORT_TEMPLATE(class, __VA_ARGS__) +#define GLF_API_TEMPLATE_STRUCT(...) ARCH_EXPORT_TEMPLATE(struct, __VA_ARGS__) +#else +#define GLF_API ARCH_IMPORT +#define GLF_API_TEMPLATE_CLASS(...) ARCH_IMPORT_TEMPLATE(class, __VA_ARGS__) +#define GLF_API_TEMPLATE_STRUCT(...) ARCH_IMPORT_TEMPLATE(struct, __VA_ARGS__) +#endif +#define GLF_LOCAL ARCH_HIDDEN #endif #endif // PXR_IMAGING_GLF_API_H diff --git a/Sources/Glf/include/Glf/bindingMap.h b/Sources/Glf/include/Glf/bindingMap.h new file mode 100644 index 0000000000..f07f02f827 --- /dev/null +++ b/Sources/Glf/include/Glf/bindingMap.h @@ -0,0 +1,144 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_BINDING_MAP_H +#define PXR_IMAGING_GLF_BINDING_MAP_H + +/// \file glf/bindingMap.h + +#include +#include "Glf/api.h" +#include "Garch/glApi.h" +#include "Tf/refBase.h" +#include "Tf/stringUtils.h" +#include "Tf/token.h" +#include "Tf/weakBase.h" + +#include "Tf/hashmap.h" + +PXR_NAMESPACE_OPEN_SCOPE + +class GlfBindingMap : public TfRefBase, public TfWeakBase +{ +public: + typedef TfHashMap BindingMap; + + GlfBindingMap() + : _samplerBindingBaseIndex(0), _uniformBindingBaseIndex(0) + { + } + + GLF_API + int GetSamplerUnit(std::string const &name); + GLF_API + int GetSamplerUnit(TfToken const &name); + + // If GetAttributeIndex is called with an unknown + // attribute token they return -1 + GLF_API + int GetAttributeIndex(std::string const &name); + GLF_API + int GetAttributeIndex(TfToken const &name); + + GLF_API + int GetUniformBinding(std::string const &name); + GLF_API + int GetUniformBinding(TfToken const &name); + + GLF_API + bool HasUniformBinding(std::string const &name) const; + GLF_API + bool HasUniformBinding(TfToken const &name) const; + + int GetNumSamplerBindings() const + { + return (int)_samplerBindings.size(); + } + + void ClearAttribBindings() + { + _attribBindings.clear(); + } + + /// \name Sampler and UBO Bindings + /// + /// Sampler units and uniform block bindings are reset and will be + /// assigned sequentially starting from the specified baseIndex. + /// This allows other subsystems to claim sampler units and uniform + /// block bindings before additional indices are assigned by this + /// binding map. + /// + /// @{ + + void ResetSamplerBindings(int baseIndex) + { + _samplerBindings.clear(); + _samplerBindingBaseIndex = baseIndex; + } + + void ResetUniformBindings(int baseIndex) + { + _uniformBindings.clear(); + _uniformBindingBaseIndex = baseIndex; + } + + /// @} + + void AddAttribBinding(TfToken const &name, int location) + { + _attribBindings[name] = location; + } + + BindingMap const &GetAttributeBindings() const + { + return _attribBindings; + } + + GLF_API + void AssignSamplerUnitsToProgram(GLuint program); + + GLF_API + void AssignUniformBindingsToProgram(GLuint program); + + GLF_API + void AddCustomBindings(GLuint program); + + GLF_API + void Debug() const; + +private: + void _AddActiveAttributeBindings(GLuint program); + void _AddActiveUniformBindings(GLuint program); + void _AddActiveUniformBlockBindings(GLuint program); + + BindingMap _attribBindings; + BindingMap _samplerBindings; + BindingMap _uniformBindings; + + int _samplerBindingBaseIndex; + int _uniformBindingBaseIndex; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // PXR_IMAGING_GLF_BINDING_MAP_H diff --git a/Sources/OpenUSD/include/imaging/glf/contextCaps.h b/Sources/Glf/include/Glf/contextCaps.h similarity index 65% rename from Sources/OpenUSD/include/imaging/glf/contextCaps.h rename to Sources/Glf/include/Glf/contextCaps.h index fe146e5019..4395667aa7 100644 --- a/Sources/OpenUSD/include/imaging/glf/contextCaps.h +++ b/Sources/Glf/include/Glf/contextCaps.h @@ -24,14 +24,12 @@ #ifndef PXR_IMAGING_GLF_CONTEXT_CAPS_H #define PXR_IMAGING_GLF_CONTEXT_CAPS_H -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/base/tf/singleton.h" - +#include +#include "Glf/api.h" +#include "Tf/singleton.h" PXR_NAMESPACE_OPEN_SCOPE - /// \class GlfContextCaps /// /// This class is intended to be a cache of the capabilites @@ -55,42 +53,41 @@ PXR_NAMESPACE_OPEN_SCOPE /// subscribe to when the caps changes, so they can /// update and invalidate. /// -class GlfContextCaps +class GlfContextCaps { public: + /// InitInstance queries the GL context for its capabilities. + /// It should be called by the application before using systems + /// that depend on the caps, such as Hydra. A good example would be + /// to pair the call to initialize after a call to initialize GL + GLF_API + static void InitInstance(); - /// InitInstance queries the GL context for its capabilities. - /// It should be called by the application before using systems - /// that depend on the caps, such as Hydra. A good example would be - /// to pair the call to initialize after a call to initialize GL - GLF_API - static void InitInstance(); + /// GetInstance() returns the filled capabilities structure. + /// This function will not populate the caps and will issue a + /// coding error if it hasn't been filled. + GLF_API + static const GlfContextCaps &GetInstance(); - /// GetInstance() returns the filled capabilities structure. - /// This function will not populate the caps and will issue a - /// coding error if it hasn't been filled. - GLF_API - static const GlfContextCaps &GetInstance(); + // GL version + int glVersion; // 400 (4.0), 410 (4.1), ... - // GL version - int glVersion; // 400 (4.0), 410 (4.1), ... + // Whether or not we are running with core profile + bool coreProfile; - // Whether or not we are running with core profile - bool coreProfile; - - // Max constants - int maxArrayTextureLayers; + // Max constants + int maxArrayTextureLayers; private: - void _LoadCaps(); - GlfContextCaps(); - ~GlfContextCaps() = default; + void _LoadCaps(); + GlfContextCaps(); + ~GlfContextCaps() = default; - // Disallow copies - GlfContextCaps(const GlfContextCaps&) = delete; - GlfContextCaps& operator=(const GlfContextCaps&) = delete; + // Disallow copies + GlfContextCaps(const GlfContextCaps &) = delete; + GlfContextCaps &operator=(const GlfContextCaps &) = delete; - friend class TfSingleton; + friend class TfSingleton; }; GLF_API_TEMPLATE_CLASS(TfSingleton); @@ -98,4 +95,3 @@ GLF_API_TEMPLATE_CLASS(TfSingleton); PXR_NAMESPACE_CLOSE_SCOPE #endif // PXR_IMAGING_GLF_CONTEXT_CAPS_H - diff --git a/Sources/OpenUSD/include/imaging/glf/debugCodes.h b/Sources/Glf/include/Glf/debugCodes.h similarity index 96% rename from Sources/OpenUSD/include/imaging/glf/debugCodes.h rename to Sources/Glf/include/Glf/debugCodes.h index 3abfb0f4a6..50b7c468c7 100644 --- a/Sources/OpenUSD/include/imaging/glf/debugCodes.h +++ b/Sources/Glf/include/Glf/debugCodes.h @@ -26,12 +26,11 @@ /// \file glf/debugCodes.h -#include "pxr/pxr.h" -#include "pxr/base/tf/debug.h" +#include +#include "Tf/debug.h" PXR_NAMESPACE_OPEN_SCOPE - TF_DEBUG_CODES( GLF_DEBUG_CONTEXT_CAPS, @@ -42,7 +41,6 @@ TF_DEBUG_CODES( ); - PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/Sources/OpenUSD/include/imaging/glf/diagnostic.h b/Sources/Glf/include/Glf/diagnostic.h similarity index 54% rename from Sources/OpenUSD/include/imaging/glf/diagnostic.h rename to Sources/Glf/include/Glf/diagnostic.h index 10eb154101..ff22962f49 100644 --- a/Sources/OpenUSD/include/imaging/glf/diagnostic.h +++ b/Sources/Glf/include/Glf/diagnostic.h @@ -26,28 +26,27 @@ /// \file glf/diagnostic.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/garch/glApi.h" -#include "pxr/base/tf/diagnostic.h" +#include +#include "Glf/api.h" +#include "Garch/glApi.h" +#include "Tf/diagnostic.h" #include #include PXR_NAMESPACE_OPEN_SCOPE - /// Posts diagnostic errors for all GL errors in the current context. /// This macro tags the diagnostic errors with the name of the calling /// function. #define GLF_POST_PENDING_GL_ERRORS() \ - GlfPostPendingGLErrors(__ARCH_PRETTY_FUNCTION__) + GlfPostPendingGLErrors(__ARCH_PRETTY_FUNCTION__) /// Posts diagnostic errors for all GL errors in the current context. GLF_API -void GlfPostPendingGLErrors(std::string const & where = std::string()); +void GlfPostPendingGLErrors(std::string const &where = std::string()); -/// Registers GlfDefaultDebugOutputMessageCallback as the +/// Registers GlfDefaultDebugOutputMessageCallback as the /// debug message callback for the current GL context. GLF_API void GlfRegisterDefaultDebugOutputMessageCallback(); @@ -57,43 +56,44 @@ void GlfRegisterDefaultDebugOutputMessageCallback(); /// for other message types. GLF_API void GlfDefaultDebugOutputMessageCallback( - GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, char const * message, GLvoid const * userParam); + GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, char const *message, GLvoid const *userParam); /// Returns a string representation of debug output enum values. GLF_API -char const * GlfDebugEnumToString(GLenum debugEnum); +char const *GlfDebugEnumToString(GLenum debugEnum); /// Emit a GlfDebugGroup tracing the current function. #define GLF_GROUP_FUNCTION() \ - GlfDebugGroup __glf_group_function(__ARCH_PRETTY_FUNCTION__) + GlfDebugGroup __glf_group_function(__ARCH_PRETTY_FUNCTION__) /// Emit a GlfDebugGroup tracing the current scope with the given string. #define GLF_GROUP_SCOPE(str) \ - GlfDebugGroup __glf_group_scope(str) + GlfDebugGroup __glf_group_scope(str) /// \class GlfDebugGroup /// /// Represents a GL debug group in Glf -/// +/// /// The debug group conditionally adds debug objects to the GL stream /// based on the value to the environment variable GLF_ENABLE_DIAGNOSTIC_TRACE. /// If set to 1 (true) the debug objects will be pushed and popped in /// the command stream as long as the GL implementation and version supports it. /// -class GlfDebugGroup { - public: - /// Pushes a new debug group onto the GL api debug trace stack - GLF_API - GlfDebugGroup(char const *message); - - /// Pops a debug group off the GL api debug trace stack - GLF_API - ~GlfDebugGroup(); - - GlfDebugGroup() = delete; - GlfDebugGroup(GlfDebugGroup const&) = delete; - GlfDebugGroup& operator =(GlfDebugGroup const&) = delete; +class GlfDebugGroup +{ +public: + /// Pushes a new debug group onto the GL api debug trace stack + GLF_API + GlfDebugGroup(char const *message); + + /// Pops a debug group off the GL api debug trace stack + GLF_API + ~GlfDebugGroup(); + + GlfDebugGroup() = delete; + GlfDebugGroup(GlfDebugGroup const &) = delete; + GlfDebugGroup &operator=(GlfDebugGroup const &) = delete; }; /// Label a buffer object to improve tracing in the debug output. @@ -112,62 +112,63 @@ void GlfDebugLabelProgram(GLuint id, char const *label); /// /// Represents a GL query object in Glf /// -class GlfGLQueryObject { +class GlfGLQueryObject +{ public: - GLF_API - GlfGLQueryObject(); - GLF_API - ~GlfGLQueryObject(); - - /// Begin query for the given \p target - /// target has to be one of - /// GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, - /// GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_PRIMITIVES_GENERATED - /// GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN - /// GL_TIME_ELAPSED, GL_TIMESTAMP - GLF_API - void Begin(GLenum target); - - /// equivalent to Begin(GL_SAMPLES_PASSED). - /// The number of samples that pass the depth test for all drawing - /// commands within the scope of the query will be returned. - GLF_API - void BeginSamplesPassed(); - - /// equivalent to Begin(GL_PRIMITIVES_GENERATED). - /// The number of primitives sent to the rasterizer by the scoped - /// drawing command will be returned. - GLF_API - void BeginPrimitivesGenerated(); - - /// equivalent to Begin(GL_TIME_ELAPSED). - /// The time that it takes for the GPU to execute all of the scoped commands - /// will be returned in nanoseconds. - GLF_API - void BeginTimeElapsed(); - - /// End query - GLF_API - void End(); - - /// Return the query result (synchronous) - /// stalls CPU until the result becomes available. - GLF_API - int64_t GetResult(); - - /// Return the query result (asynchronous) - /// returns 0 if the result hasn't been available. - GLF_API - int64_t GetResultNoWait(); - - GlfGLQueryObject(GlfGLQueryObject const&) = delete; - GlfGLQueryObject& operator =(GlfGLQueryObject const&) = delete; + GLF_API + GlfGLQueryObject(); + GLF_API + ~GlfGLQueryObject(); + + /// Begin query for the given \p target + /// target has to be one of + /// GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, + /// GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_PRIMITIVES_GENERATED + /// GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN + /// GL_TIME_ELAPSED, GL_TIMESTAMP + GLF_API + void Begin(GLenum target); + + /// equivalent to Begin(GL_SAMPLES_PASSED). + /// The number of samples that pass the depth test for all drawing + /// commands within the scope of the query will be returned. + GLF_API + void BeginSamplesPassed(); + + /// equivalent to Begin(GL_PRIMITIVES_GENERATED). + /// The number of primitives sent to the rasterizer by the scoped + /// drawing command will be returned. + GLF_API + void BeginPrimitivesGenerated(); + + /// equivalent to Begin(GL_TIME_ELAPSED). + /// The time that it takes for the GPU to execute all of the scoped commands + /// will be returned in nanoseconds. + GLF_API + void BeginTimeElapsed(); + + /// End query + GLF_API + void End(); + + /// Return the query result (synchronous) + /// stalls CPU until the result becomes available. + GLF_API + int64_t GetResult(); + + /// Return the query result (asynchronous) + /// returns 0 if the result hasn't been available. + GLF_API + int64_t GetResultNoWait(); + + GlfGLQueryObject(GlfGLQueryObject const &) = delete; + GlfGLQueryObject &operator=(GlfGLQueryObject const &) = delete; + private: - GLuint _id; - GLenum _target; + GLuint _id; + GLenum _target; }; - PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/Sources/Glf/include/Glf/drawTarget.h b/Sources/Glf/include/Glf/drawTarget.h new file mode 100644 index 0000000000..dbdd108f61 --- /dev/null +++ b/Sources/Glf/include/Glf/drawTarget.h @@ -0,0 +1,303 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_DRAW_TARGET_H +#define PXR_IMAGING_GLF_DRAW_TARGET_H + +/// \file glf/drawTarget.h + +#include +#include "Glf/api.h" +#include "Glf/texture.h" +#include "Garch/glApi.h" + +#include "Gf/vec2i.h" +#include "Gf/matrix4d.h" +#include "Tf/declarePtrs.h" +#include "Tf/refBase.h" +#include "Tf/weakBase.h" + +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DECLARE_WEAK_AND_REF_PTRS(GlfDrawTarget); +typedef std::shared_ptr GlfGLContextSharedPtr; + +/// \class GlfDrawTarget +/// +/// A class representing a GL render target with mutliple image attachments. +/// +/// A DrawTarget is essentially a custom render pass into which several +/// arbitrary variables can be output into. These can later be used as +/// texture samplers by GLSL shaders. +/// +/// The DrawTarget maintains a map of named attachments that correspond +/// to GL_TEXTURE_2D mages. By default, DrawTargets also create a depth +/// component that is used both as a depth buffer during the draw pass, +/// and can later be accessed as a regular GL_TEXTURE_2D data. Stencils +/// are also available (by setting the format to GL_DEPTH_STENCIL and +/// the internalFormat to GL_DEPTH24_STENCIL8) +/// +class GlfDrawTarget : public TfRefBase, public TfWeakBase +{ +public: + typedef GlfDrawTarget This; + +public: + /// Returns a new instance. + GLF_API + static GlfDrawTargetRefPtr New(GfVec2i const &size, + bool requestMSAA = false); + + /// Returns a new instance. + /// GL framebuffers cannot be shared across contexts, but texture + /// attachments can. In order to reflect this, GlfDrawTargets hold + /// onto their maps of attachments through a RefPtr that can be shared + /// by multiple GlfDrawTargets, one for each of the active GL contexts + /// (ex. one for each active QT viewer). + /// This constructor creates a new framebuffer, but populates its map of + /// attachments by sharing the RefPtr of the source GlfDrawTarget. + GLF_API + static GlfDrawTargetRefPtr New(GlfDrawTargetPtr const &drawtarget); + + class Attachment : public GlfTexture + { + public: + typedef TfDeclarePtrs::RefPtr AttachmentRefPtr; + + GLF_API + static AttachmentRefPtr New(int glIndex, GLenum format, GLenum type, + GLenum internalFormat, GfVec2i size, + unsigned int numSamples); + + GLF_API + ~Attachment() override; + + /// Returns the GL texture index (can be used as any regular GL texture) + GLuint GetGlTextureName() override; + + /// Returns the GL texture index multisampled of this attachment + GLuint GetGlTextureMSName() const { return _textureNameMS; } + + /// Returns the GL format of the texture (GL_RGB, GL_DEPTH_COMPONENT...) + GLenum GetFormat() const { return _format; } + + /// Returns the GL type of the texture (GL_BYTE, GL_INT, GL_FLOAT...) + GLenum GetType() const { return _type; } + + /// Returns the GL internalFormat of the texture + GLenum GetInternalFormat() const { return _internalFormat; } + + /// Returns the GL attachment point index in the framebuffer. + int GetAttach() const { return _glIndex; } + + /// Resize the attachment recreating the texture + GLF_API + void ResizeTexture(const GfVec2i &size); + + // GlfTexture overrides + GLF_API + BindingVector GetBindings(TfToken const &identifier, + GLuint samplerName) override; + GLF_API + VtDictionary GetTextureInfo(bool forceLoad) override; + + /// Updates the contents signature for the underlying texture + /// to allow downstream consumers to know that the texture image + /// data may have changed. + GLF_API + void TouchContents(); + + private: + Attachment(int glIndex, GLenum format, GLenum type, + GLenum internalFormat, GfVec2i size, + unsigned int numSamples); + + void _GenTexture(); + void _DeleteTexture(); + + GLuint _textureName; + GLuint _textureNameMS; + + GLenum _format, + _type, + _internalFormat; + + int _glIndex; + + GfVec2i _size; + + unsigned int _numSamples; + }; + + typedef TfDeclarePtrs::RefPtr AttachmentRefPtr; + + typedef std::map AttachmentsMap; + + /// Add an attachment to the DrawTarget. + GLF_API + void AddAttachment(std::string const &name, + GLenum format, GLenum type, GLenum internalFormat); + + /// Removes the named attachment from the DrawTarget. + GLF_API + void DeleteAttachment(std::string const &name); + + /// Clears all the attachments for this DrawTarget. + GLF_API + void ClearAttachments(); + + /// Copies the list of attachments from DrawTarget. + GLF_API + void CloneAttachments(GlfDrawTargetPtr const &drawtarget); + + /// Returns the list of Attachments for this DrawTarget. + GLF_API + AttachmentsMap const &GetAttachments() const; + + /// Returns the attachment with a given name or TfNullPtr; + GLF_API + AttachmentRefPtr GetAttachment(std::string const &name); + + /// Write the Attachment buffer to an image file (debugging). + GLF_API + bool WriteToFile(std::string const &name, + std::string const &filename, + GfMatrix4d const &viewMatrix = GfMatrix4d(1), + GfMatrix4d const &projectionMatrix = GfMatrix4d(1)); + + /// Resize the DrawTarget. + GLF_API + void SetSize(GfVec2i); + + /// Returns the size of the DrawTarget. + GfVec2i const &GetSize() const { return _size; } + + /// Returns if the draw target uses msaa + bool HasMSAA() const { return (_numSamples > 1); } + + /// Returns the framebuffer object Id. + GLF_API + GLuint GetFramebufferId() const; + + /// Returns the id of the framebuffer object with MSAA buffers. + GLF_API + GLuint GetFramebufferMSId() const; + + /// Binds the framebuffer. + GLF_API + void Bind(); + + /// Unbinds the framebuffer. + GLF_API + void Unbind(); + + /// Returns whether the framebuffer is currently bound. + GLF_API + bool IsBound() const; + + /// Resolve the MSAA framebuffer to a regular framebuffer. If there + /// is no MSAA enabled, this function does nothing. + GLF_API + void Resolve(); + + /// Resolve several MSAA framebuffers at once. If any framebuffers don't + /// have MSAA enabled, nothing happens to them. + GLF_API + static void Resolve(const std::vector &drawTargets); + + /// Updates the contents signature for attached textures + /// to allow downstream consumers to know that the texture image + /// data may have changed. + GLF_API + void TouchContents(); + + /// Returns whether the enclosed framebuffer object is complete. + /// If \a reason is non-NULL, and this framebuffer is not valid, + /// sets \a reason to the reason why not. + GLF_API + bool IsValid(std::string *reason = NULL); + +protected: + /// Weak/Ref-based container for the the map of texture attachments. + /// Multiple GlfDrawTargets can jointly share their attachment textures : + /// this construction allows the use of a RefPtr on the map of attachments. + class AttachmentsContainer : public TfRefBase, public TfWeakBase + { + public: + AttachmentsMap attachments; + }; + + GLF_API + GlfDrawTarget(GfVec2i const &size, bool requestMSAA); + + GLF_API + GlfDrawTarget(GlfDrawTargetPtr const &drawtarget); + + GLF_API + virtual ~GlfDrawTarget(); + +private: + void _GenFrameBuffer(); + + void _BindAttachment(GlfDrawTarget::AttachmentRefPtr const &a); + + GLuint _AllocAttachment(GLenum format, GLenum type); + + AttachmentsMap &_GetAttachments() const; + + void _DeleteAttachments(); + + void _AllocDepth(); + + bool _Validate(std::string *reason = NULL); + + void _SaveBindingState(); + + void _RestoreBindingState(); + + void _Resolve(); + + GLuint _framebuffer; + GLuint _framebufferMS; + + GLuint _unbindRestoreReadFB, + _unbindRestoreDrawFB; + + int _bindDepth; + + GfVec2i _size; + + unsigned int _numSamples; + + TfRefPtr _attachmentsPtr; + GlfGLContextSharedPtr _owningContext; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // GLF_DRAW_TARGET_H diff --git a/Sources/OpenUSD/include/imaging/glf/glContext.h b/Sources/Glf/include/Glf/glContext.h similarity index 58% rename from Sources/OpenUSD/include/imaging/glf/glContext.h rename to Sources/Glf/include/Glf/glContext.h index 622bba0dbc..ef6c73a251 100644 --- a/Sources/OpenUSD/include/imaging/glf/glContext.h +++ b/Sources/Glf/include/Glf/glContext.h @@ -24,15 +24,14 @@ #ifndef PXR_IMAGING_GLF_GL_CONTEXT_H #define PXR_IMAGING_GLF_GL_CONTEXT_H -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/base/arch/threads.h" +#include +#include "Glf/api.h" +#include "Arch/threads.h" #include PXR_NAMESPACE_OPEN_SCOPE - typedef std::shared_ptr GlfGLContextSharedPtr; /// \class GlfGLContext @@ -52,81 +51,81 @@ typedef std::shared_ptr GlfGLContextSharedPtr; class GlfGLContext { public: - GLF_API - virtual ~GlfGLContext(); + GLF_API + virtual ~GlfGLContext(); - // Disallow copies - GlfGLContext(const GlfGLContext&) = delete; - GlfGLContext& operator=(const GlfGLContext&) = delete; + // Disallow copies + GlfGLContext(const GlfGLContext &) = delete; + GlfGLContext &operator=(const GlfGLContext &) = delete; - /// Returns an instance for the current GL context. - GLF_API - static GlfGLContextSharedPtr GetCurrentGLContext(); + /// Returns an instance for the current GL context. + GLF_API + static GlfGLContextSharedPtr GetCurrentGLContext(); - /// Returns an instance for the shared GL context. - GLF_API - static GlfGLContextSharedPtr GetSharedGLContext(); + /// Returns an instance for the shared GL context. + GLF_API + static GlfGLContextSharedPtr GetSharedGLContext(); - /// Makes \p context current if valid, otherwise makes no context current. - GLF_API - static void MakeCurrent(const GlfGLContextSharedPtr& context); + /// Makes \p context current if valid, otherwise makes no context current. + GLF_API + static void MakeCurrent(const GlfGLContextSharedPtr &context); - /// Returns \c true if \a context1 and \a context2 are sharing. - GLF_API - static bool AreSharing(GlfGLContextSharedPtr const & context1, - GlfGLContextSharedPtr const & context2); + /// Returns \c true if \a context1 and \a context2 are sharing. + GLF_API + static bool AreSharing(GlfGLContextSharedPtr const &context1, + GlfGLContextSharedPtr const &context2); - /// Returns whether this interface has been initialized. - GLF_API - static bool IsInitialized(); + /// Returns whether this interface has been initialized. + GLF_API + static bool IsInitialized(); - /// Returns \c true if this context is current. - GLF_API - bool IsCurrent() const; + /// Returns \c true if this context is current. + GLF_API + bool IsCurrent() const; private: - /// Makes this context current. - /// - /// If the context is not valid this does nothing. - void MakeCurrent(); + /// Makes this context current. + /// + /// If the context is not valid this does nothing. + void MakeCurrent(); public: - /// Makes no context current. - GLF_API - static void DoneCurrent(); - - /// Returns \c true if this context is sharing with \a otherContext. - GLF_API - bool IsSharing(GlfGLContextSharedPtr const & otherContext); - - /// Returns \c true if this context is valid. - virtual bool IsValid() const = 0; - - /// Creates a new GlfContext that shares GL resources with this context. - /// The purpose of this function is to be able to create a new GL context - /// on a second thread that shares with the context on the main-thread. - /// If the GlfContext implementation does not support sharing contexts - /// null is returned. Example usage: - /// Main-thread: - /// RegisterGLContextCallbacks(); - /// GlfGLContext::MakeCurrent(...); - /// Second-thread: - /// s = GetCurrentGLContext(); - /// c = s->CreateSharingContext(); - virtual GlfGLContextSharedPtr CreateSharingContext() {return nullptr;} + /// Makes no context current. + GLF_API + static void DoneCurrent(); + + /// Returns \c true if this context is sharing with \a otherContext. + GLF_API + bool IsSharing(GlfGLContextSharedPtr const &otherContext); + + /// Returns \c true if this context is valid. + virtual bool IsValid() const = 0; + + /// Creates a new GlfContext that shares GL resources with this context. + /// The purpose of this function is to be able to create a new GL context + /// on a second thread that shares with the context on the main-thread. + /// If the GlfContext implementation does not support sharing contexts + /// null is returned. Example usage: + /// Main-thread: + /// RegisterGLContextCallbacks(); + /// GlfGLContext::MakeCurrent(...); + /// Second-thread: + /// s = GetCurrentGLContext(); + /// c = s->CreateSharingContext(); + virtual GlfGLContextSharedPtr CreateSharingContext() { return nullptr; } protected: - GLF_API - GlfGLContext(); + GLF_API + GlfGLContext(); - /// Makes this context current. - virtual void _MakeCurrent() = 0; + /// Makes this context current. + virtual void _MakeCurrent() = 0; - /// Returns \c true if this context is sharing with \a rhs. - virtual bool _IsSharing(const GlfGLContextSharedPtr& rhs) const = 0; + /// Returns \c true if this context is sharing with \a rhs. + virtual bool _IsSharing(const GlfGLContextSharedPtr &rhs) const = 0; - /// Returns \c true if this context is equal to \p rhs. - virtual bool _IsEqual(const GlfGLContextSharedPtr& rhs) const = 0; + /// Returns \c true if this context is equal to \p rhs. + virtual bool _IsEqual(const GlfGLContextSharedPtr &rhs) const = 0; }; /// \class GlfGLContextScopeHolder @@ -170,26 +169,26 @@ class GlfGLContext class GlfGLContextScopeHolder { public: - /// Make the given context current and restore the current context - /// when this object is destroyed. - GLF_API - explicit GlfGLContextScopeHolder(const GlfGLContextSharedPtr& newContext); + /// Make the given context current and restore the current context + /// when this object is destroyed. + GLF_API + explicit GlfGLContextScopeHolder(const GlfGLContextSharedPtr &newContext); - GLF_API - ~GlfGLContextScopeHolder(); + GLF_API + ~GlfGLContextScopeHolder(); - GlfGLContextScopeHolder(const GlfGLContextScopeHolder&) = delete; - GlfGLContextScopeHolder& operator=(const GlfGLContextScopeHolder) = delete; + GlfGLContextScopeHolder(const GlfGLContextScopeHolder &) = delete; + GlfGLContextScopeHolder &operator=(const GlfGLContextScopeHolder) = delete; protected: - GLF_API - void _MakeNewContextCurrent(); - GLF_API - void _RestoreOldContext(); + GLF_API + void _MakeNewContextCurrent(); + GLF_API + void _RestoreOldContext(); private: - GlfGLContextSharedPtr _newContext; - GlfGLContextSharedPtr _oldContext; + GlfGLContextSharedPtr _newContext; + GlfGLContextSharedPtr _oldContext; }; /// \class GlfSharedGLContextScopeHolder @@ -236,20 +235,20 @@ class GlfGLContextScopeHolder class GlfSharedGLContextScopeHolder final : private GlfGLContextScopeHolder { public: - GlfSharedGLContextScopeHolder() : - GlfGLContextScopeHolder(_GetSharedContext()) - { - // Do nothing - } + GlfSharedGLContextScopeHolder() : GlfGLContextScopeHolder(_GetSharedContext()) + { + // Do nothing + } private: - static GlfGLContextSharedPtr _GetSharedContext() + static GlfGLContextSharedPtr _GetSharedContext() + { + if (GlfGLContext::IsInitialized() && ArchIsMainThread()) { - if (GlfGLContext::IsInitialized() && ArchIsMainThread()) { - return GlfGLContext::GetSharedGLContext(); - } - return GlfGLContextSharedPtr(); + return GlfGLContext::GetSharedGLContext(); } + return GlfGLContextSharedPtr(); + } }; #define API_GLF_HAS_ANY_GL_CONTEXT_SCOPE_HOLDER 1 @@ -303,26 +302,27 @@ class GlfSharedGLContextScopeHolder final : private GlfGLContextScopeHolder class GlfAnyGLContextScopeHolder final : private GlfGLContextScopeHolder { public: - GlfAnyGLContextScopeHolder() : - GlfGLContextScopeHolder(_GetAnyContext()) - { - // Do nothing - } + GlfAnyGLContextScopeHolder() : GlfGLContextScopeHolder(_GetAnyContext()) + { + // Do nothing + } private: - static GlfGLContextSharedPtr _GetAnyContext() + static GlfGLContextSharedPtr _GetAnyContext() + { + if (GlfGLContext::IsInitialized() && ArchIsMainThread()) { - if (GlfGLContext::IsInitialized() && ArchIsMainThread()) { - GlfGLContextSharedPtr const current = - GlfGLContext::GetCurrentGLContext(); - if (!(current && - current->IsValid() && - current->IsSharing(GlfGLContext::GetSharedGLContext()))) { - return GlfGLContext::GetSharedGLContext(); - } - } - return GlfGLContextSharedPtr(); + GlfGLContextSharedPtr const current = + GlfGLContext::GetCurrentGLContext(); + if (!(current && + current->IsValid() && + current->IsSharing(GlfGLContext::GetSharedGLContext()))) + { + return GlfGLContext::GetSharedGLContext(); + } } + return GlfGLContextSharedPtr(); + } }; /// \class GlfGLContextRegistrationInterface @@ -335,32 +335,31 @@ class GlfAnyGLContextScopeHolder final : private GlfGLContextScopeHolder class GlfGLContextRegistrationInterface { public: - GLF_API - virtual ~GlfGLContextRegistrationInterface(); - - // Disallow copies - GlfGLContextRegistrationInterface( - const GlfGLContextRegistrationInterface&) = delete; - GlfGLContextRegistrationInterface& operator=( - const GlfGLContextRegistrationInterface&) = delete; - - /// If this GLContext system supports a shared context this should - /// return it. This will be called at most once. - virtual GlfGLContextSharedPtr GetShared() = 0; - - /// Whatever your GLContext system thinks is the current GL context - /// may not really be the current context if another system has since - /// changed the context. This method should return what it thinks is - /// the current context. If it thinks there is no current context it - /// should return \c NULL. - virtual GlfGLContextSharedPtr GetCurrent() = 0; + GLF_API + virtual ~GlfGLContextRegistrationInterface(); + + // Disallow copies + GlfGLContextRegistrationInterface( + const GlfGLContextRegistrationInterface &) = delete; + GlfGLContextRegistrationInterface &operator=( + const GlfGLContextRegistrationInterface &) = delete; + + /// If this GLContext system supports a shared context this should + /// return it. This will be called at most once. + virtual GlfGLContextSharedPtr GetShared() = 0; + + /// Whatever your GLContext system thinks is the current GL context + /// may not really be the current context if another system has since + /// changed the context. This method should return what it thinks is + /// the current context. If it thinks there is no current context it + /// should return \c NULL. + virtual GlfGLContextSharedPtr GetCurrent() = 0; protected: - GLF_API - GlfGLContextRegistrationInterface(); + GLF_API + GlfGLContextRegistrationInterface(); }; - PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/Sources/OpenUSD/include/imaging/glf/glContextRegistry.h b/Sources/Glf/include/Glf/glContextRegistry.h similarity index 53% rename from Sources/OpenUSD/include/imaging/glf/glContextRegistry.h rename to Sources/Glf/include/Glf/glContextRegistry.h index 7b1cd42c49..509ff0f0f9 100644 --- a/Sources/OpenUSD/include/imaging/glf/glContextRegistry.h +++ b/Sources/Glf/include/Glf/glContextRegistry.h @@ -26,16 +26,15 @@ /// \file glf/glContextRegistry.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/glContext.h" -#include "pxr/base/tf/singleton.h" +#include +#include "Glf/glContext.h" +#include "Tf/singleton.h" #include #include PXR_NAMESPACE_OPEN_SCOPE - struct GlfGLContextRegistry_Data; typedef std::shared_ptr GlfGLContextSharedPtr; @@ -47,48 +46,47 @@ typedef std::shared_ptr GlfGLContextSharedPtr; class GlfGLContextRegistry { public: - static GlfGLContextRegistry& GetInstance() - { - return TfSingleton::GetInstance(); - } + static GlfGLContextRegistry &GetInstance() + { + return TfSingleton::GetInstance(); + } - /// Returns whether the registry has any registered interfaces. - bool IsInitialized() const; + /// Returns whether the registry has any registered interfaces. + bool IsInitialized() const; - /// Add a registration object to the registry. This takes ownership - /// of the object. - void Add(GlfGLContextRegistrationInterface*); + /// Add a registration object to the registry. This takes ownership + /// of the object. + void Add(GlfGLContextRegistrationInterface *); - /// Returns the shared context, if any. - GlfGLContextSharedPtr GetShared(); + /// Returns the shared context, if any. + GlfGLContextSharedPtr GetShared(); - /// Returns the context that matches the raw context, if any. - GlfGLContextSharedPtr GetCurrent(); + /// Returns the context that matches the raw context, if any. + GlfGLContextSharedPtr GetCurrent(); - /// Registers this context. It must be current. - void DidMakeCurrent(const GlfGLContextSharedPtr& context); + /// Registers this context. It must be current. + void DidMakeCurrent(const GlfGLContextSharedPtr &context); - /// Removes the context. - void Remove(const GlfGLContext* context); + /// Removes the context. + void Remove(const GlfGLContext *context); private: - GlfGLContextRegistry(); - ~GlfGLContextRegistry(); + GlfGLContextRegistry(); + ~GlfGLContextRegistry(); - // Non-copyable - GlfGLContextRegistry(const GlfGLContextRegistry &) = delete; - GlfGLContextRegistry &operator=(const GlfGLContextRegistry &) = delete; + // Non-copyable + GlfGLContextRegistry(const GlfGLContextRegistry &) = delete; + GlfGLContextRegistry &operator=(const GlfGLContextRegistry &) = delete; - friend class TfSingleton; + friend class TfSingleton; private: - std::vector> _interfaces; - bool _sharedContextInitialized; - GlfGLContextSharedPtr _shared; - std::unique_ptr _data; + std::vector> _interfaces; + bool _sharedContextInitialized; + GlfGLContextSharedPtr _shared; + std::unique_ptr _data; }; - PXR_NAMESPACE_CLOSE_SCOPE -#endif // PXR_IMAGING_GLF_GL_CONTEXT_REGISTRY_H +#endif // PXR_IMAGING_GLF_GL_CONTEXT_REGISTRY_H diff --git a/Sources/OpenUSD/include/imaging/glf/glRawContext.h b/Sources/Glf/include/Glf/glRawContext.h similarity index 57% rename from Sources/OpenUSD/include/imaging/glf/glRawContext.h rename to Sources/Glf/include/Glf/glRawContext.h index 8580ece6b4..4c3d9a26a3 100644 --- a/Sources/OpenUSD/include/imaging/glf/glRawContext.h +++ b/Sources/Glf/include/Glf/glRawContext.h @@ -26,55 +26,54 @@ /// \file glf/glRawContext.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/glf/glContext.h" -#include "pxr/imaging/garch/glPlatformContext.h" +#include +#include "Glf/api.h" +#include "Glf/glContext.h" +#include "Garch/glPlatformContext.h" #include PXR_NAMESPACE_OPEN_SCOPE - typedef std::shared_ptr GlfGLRawContextSharedPtr; -class GlfGLRawContext : public GlfGLContext { +class GlfGLRawContext : public GlfGLContext +{ public: - /// Returns a new object with the current context. - GLF_API - static GlfGLRawContextSharedPtr New(); + /// Returns a new object with the current context. + GLF_API + static GlfGLRawContextSharedPtr New(); - /// Returns a new object with the given state. - GLF_API - static GlfGLRawContextSharedPtr New(const GarchGLPlatformContextState&); + /// Returns a new object with the given state. + GLF_API + static GlfGLRawContextSharedPtr New(const GarchGLPlatformContextState &); - GLF_API - virtual ~GlfGLRawContext(); + GLF_API + virtual ~GlfGLRawContext(); - /// Returns the held state. - const GarchGLPlatformContextState& GetState() const { return _state; } + /// Returns the held state. + const GarchGLPlatformContextState &GetState() const { return _state; } - // GlfGLContext overrides - GLF_API - virtual bool IsValid() const; + // GlfGLContext overrides + GLF_API + virtual bool IsValid() const; protected: - // GlfGLContext overrides - GLF_API - virtual void _MakeCurrent(); - GLF_API - virtual bool _IsSharing(const GlfGLContextSharedPtr& rhs) const; - GLF_API - virtual bool _IsEqual(const GlfGLContextSharedPtr& rhs) const; + // GlfGLContext overrides + GLF_API + virtual void _MakeCurrent(); + GLF_API + virtual bool _IsSharing(const GlfGLContextSharedPtr &rhs) const; + GLF_API + virtual bool _IsEqual(const GlfGLContextSharedPtr &rhs) const; private: - GlfGLRawContext(const GarchGLPlatformContextState&); + GlfGLRawContext(const GarchGLPlatformContextState &); private: - GarchGLPlatformContextState _state; + GarchGLPlatformContextState _state; }; - PXR_NAMESPACE_CLOSE_SCOPE -#endif // PXR_IMAGING_GLF_GL_RAW_CONTEXT_H +#endif // PXR_IMAGING_GLF_GL_RAW_CONTEXT_H diff --git a/Sources/OpenUSD/include/imaging/glf/info.h b/Sources/Glf/include/Glf/info.h similarity index 92% rename from Sources/OpenUSD/include/imaging/glf/info.h rename to Sources/Glf/include/Glf/info.h index 63596b6984..725ea5bbb8 100644 --- a/Sources/OpenUSD/include/imaging/glf/info.h +++ b/Sources/Glf/include/Glf/info.h @@ -26,19 +26,18 @@ /// \file glf/info.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" +#include +#include "Glf/api.h" #include PXR_NAMESPACE_OPEN_SCOPE - /// Tests for GL extension support. /// /// Returns \c true if each extension name listed in \a extensions /// is supported by the current GL context. GLF_API -bool GlfHasExtensions(std::string const & extensions); +bool GlfHasExtensions(std::string const &extensions); PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/include/Glf/simpleLight.h b/Sources/Glf/include/Glf/simpleLight.h new file mode 100644 index 0000000000..48e435ef0b --- /dev/null +++ b/Sources/Glf/include/Glf/simpleLight.h @@ -0,0 +1,238 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_SIMPLE_LIGHT_H +#define PXR_IMAGING_GLF_SIMPLE_LIGHT_H + +/// \file glf/simpleLight.h + +#include +#include "Glf/api.h" +#include "Gf/matrix4d.h" +#include "Gf/vec3f.h" +#include "Gf/vec4f.h" +#include "Sdf/path.h" +#include "Sdf/assetPath.h" + +#include "Tf/token.h" +#include "Vt/array.h" +#include "Vt/dictionary.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +class GlfSimpleLight final +{ +public: + GLF_API + GlfSimpleLight(GfVec4f const &position = GfVec4f(0.0, 0.0, 0.0, 1.0)); + GLF_API + ~GlfSimpleLight(); + + GLF_API + GfMatrix4d const &GetTransform() const; + GLF_API + void SetTransform(GfMatrix4d const &mat); + + GLF_API + GfVec4f const &GetAmbient() const; + GLF_API + void SetAmbient(GfVec4f const &ambient); + + GLF_API + GfVec4f const &GetDiffuse() const; + GLF_API + void SetDiffuse(GfVec4f const &diffuse); + + GLF_API + GfVec4f const &GetSpecular() const; + GLF_API + void SetSpecular(GfVec4f const &specular); + + GLF_API + GfVec4f const &GetPosition() const; + GLF_API + void SetPosition(GfVec4f const &position); + + GLF_API + GfVec3f const &GetSpotDirection() const; + GLF_API + void SetSpotDirection(GfVec3f const &spotDirection); + + GLF_API + float const &GetSpotCutoff() const; + GLF_API + void SetSpotCutoff(float const &spotCutoff); + + GLF_API + float const &GetSpotFalloff() const; + GLF_API + void SetSpotFalloff(float const &spotFalloff); + + GLF_API + GfVec3f const &GetAttenuation() const; + GLF_API + void SetAttenuation(GfVec3f const &attenuation); + + GLF_API + std::vector const &GetShadowMatrices() const; + GLF_API + void SetShadowMatrices(std::vector const &matrix); + + GLF_API + int GetShadowResolution() const; + GLF_API + void SetShadowResolution(int resolution); + + GLF_API + float GetShadowBias() const; + GLF_API + void SetShadowBias(float bias); + + GLF_API + float GetShadowBlur() const; + GLF_API + void SetShadowBlur(float blur); + + GLF_API + int GetShadowIndexStart() const; + GLF_API + void SetShadowIndexStart(int shadowStart); + + GLF_API + int GetShadowIndexEnd() const; + GLF_API + void SetShadowIndexEnd(int shadowEnd); + + GLF_API + bool HasShadow() const; + GLF_API + void SetHasShadow(bool hasShadow); + + GLF_API + bool HasIntensity() const; + GLF_API + void SetHasIntensity(bool hasIntensity); + + GLF_API + bool IsCameraSpaceLight() const; + GLF_API + + void SetIsCameraSpaceLight(bool isCameraSpaceLight); + GLF_API + SdfPath const &GetID() const; + GLF_API + void SetID(SdfPath const &id); + + GLF_API + bool IsDomeLight() const; + GLF_API + void SetIsDomeLight(bool isDomeLight); + + /// The path to the (unprocessed) environment map texture. + /// + /// All textures actually used by the dome light (irradiance, prefilter, + /// brdf) are derived from this texture in a pre-calculation step. + GLF_API + const SdfAssetPath &GetDomeLightTextureFile() const; + GLF_API + void SetDomeLightTextureFile(const SdfAssetPath &); + + /// \name Post Surface Lighting + /// + /// Post surface lighting is evaluated after other surface illumination + /// and can be used to implement lighting effects beyond those that + /// correspond to basic positional lighting, e.g. range base fog, etc. + /// + /// @{ + + GLF_API + TfToken const &GetPostSurfaceIdentifier() const; + GLF_API + std::string const &GetPostSurfaceShaderSource() const; + GLF_API + VtUCharArray const &GetPostSurfaceShaderParams() const; + + GLF_API + void SetPostSurfaceParams(TfToken const &identifier, + std::string const &shaderSource, + VtUCharArray const &shaderParams); + + /// @} + + GLF_API + bool operator==(GlfSimpleLight const &other) const; + GLF_API + bool operator!=(GlfSimpleLight const &other) const; + +private: + GLF_API + friend std::ostream &operator<<(std::ostream &out, + const GlfSimpleLight &v); + GfVec4f _ambient; + GfVec4f _diffuse; + GfVec4f _specular; + GfVec4f _position; + GfVec3f _spotDirection; + float _spotCutoff; + float _spotFalloff; + GfVec3f _attenuation; + bool _isCameraSpaceLight; + bool _hasIntensity; + + bool _hasShadow; + int _shadowResolution; + float _shadowBias; + float _shadowBlur; + int _shadowIndexStart; + int _shadowIndexEnd; + + GfMatrix4d _transform; + std::vector _shadowMatrices; + + // domeLight specific parameters + bool _isDomeLight; + // path to texture for dome light. + SdfAssetPath _domeLightTextureFile; + + TfToken _postSurfaceIdentifier; + std::string _postSurfaceShaderSource; + VtUCharArray _postSurfaceShaderParams; + + SdfPath _id; +}; + +// VtValue requirements +GLF_API +std::ostream &operator<<(std::ostream &out, const GlfSimpleLight &v); + +typedef std::vector GlfSimpleLightVector; + +// VtValue requirements +GLF_API +std::ostream &operator<<(std::ostream &out, const GlfSimpleLightVector &pv); + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/Sources/Glf/include/Glf/simpleLightingContext.h b/Sources/Glf/include/Glf/simpleLightingContext.h new file mode 100644 index 0000000000..c1b28c2485 --- /dev/null +++ b/Sources/Glf/include/Glf/simpleLightingContext.h @@ -0,0 +1,179 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_SIMPLE_LIGHTING_CONTEXT_H +#define PXR_IMAGING_GLF_SIMPLE_LIGHTING_CONTEXT_H + +/// \file glf/simpleLightingContext.h + +#include +#include "Glf/api.h" +#include "Glf/simpleLight.h" +#include "Glf/simpleMaterial.h" +#include "Glf/simpleShadowArray.h" + +#include "Gf/matrix4d.h" +#include "Gf/vec4f.h" + +#include "Tf/declarePtrs.h" +#include "Tf/refBase.h" +#include "Tf/weakBase.h" +#include "Tf/token.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DECLARE_WEAK_AND_REF_PTRS(GlfBindingMap); +TF_DECLARE_WEAK_AND_REF_PTRS(GlfUniformBlock); +TF_DECLARE_WEAK_AND_REF_PTRS(GlfSimpleLightingContext); +TF_DECLARE_WEAK_AND_REF_PTRS(GlfSimpleShadowArray); + +class GlfSimpleLightingContext : public TfRefBase, public TfWeakBase +{ +public: + typedef GlfSimpleLightingContext This; + + GLF_API + static GlfSimpleLightingContextRefPtr New(); + + GLF_API + void SetLights(GlfSimpleLightVector const &lights); + GLF_API + GlfSimpleLightVector const &GetLights() const; + + // returns the effective number of lights taken into account + // in composable/compatible shader constraints + GLF_API + int GetNumLightsUsed() const; + + // returns the number of shadow maps needed, by summing shadow maps + // allocated to each light. + GLF_API + int ComputeNumShadowsUsed() const; + + GLF_API + void SetShadows(GlfSimpleShadowArrayRefPtr const &shadows); + GLF_API + GlfSimpleShadowArrayRefPtr const &GetShadows() const; + + GLF_API + void SetMaterial(GlfSimpleMaterial const &material); + GLF_API + GlfSimpleMaterial const &GetMaterial() const; + + GLF_API + void SetSceneAmbient(GfVec4f const &sceneAmbient); + GLF_API + GfVec4f const &GetSceneAmbient() const; + + GLF_API + void SetCamera(GfMatrix4d const &worldToViewMatrix, + GfMatrix4d const &projectionMatrix); + + GLF_API + void SetUseLighting(bool val); + GLF_API + bool GetUseLighting() const; + + // returns true if any light has shadow enabled. + GLF_API + bool GetUseShadows() const; + + GLF_API + void SetUseColorMaterialDiffuse(bool val); + GLF_API + bool GetUseColorMaterialDiffuse() const; + + GLF_API + void InitUniformBlockBindings(GlfBindingMapPtr const &bindingMap) const; + GLF_API + void InitSamplerUnitBindings(GlfBindingMapPtr const &bindingMap) const; + + GLF_API + void BindUniformBlocks(GlfBindingMapPtr const &bindingMap); + GLF_API + void BindSamplers(GlfBindingMapPtr const &bindingMap); + + GLF_API + void UnbindSamplers(GlfBindingMapPtr const &bindingMap); + + GLF_API + void SetStateFromOpenGL(); + + /// \name Post Surface Lighting + /// + /// This context can provide additional shader source, currently + /// used to implement post surface lighting, along with a hash + /// to help de-duplicate use by client shader programs. + /// + /// @{ + + GLF_API + size_t ComputeShaderSourceHash(); + + GLF_API + std::string const &ComputeShaderSource(TfToken const &shaderStageKey); + + /// @} + +protected: + GLF_API + GlfSimpleLightingContext(); + GLF_API + ~GlfSimpleLightingContext(); + + void _ComputePostSurfaceShaderState(); + void _BindPostSurfaceShaderParams(GlfBindingMapPtr const &bindingMap); + +private: + GlfSimpleLightVector _lights; + GlfSimpleShadowArrayRefPtr _shadows; + + GfMatrix4d _worldToViewMatrix; + GfMatrix4d _projectionMatrix; + + GlfSimpleMaterial _material; + GfVec4f _sceneAmbient; + + bool _useLighting; + bool _useShadows; + bool _useColorMaterialDiffuse; + + GlfUniformBlockRefPtr _lightingUniformBlock; + GlfUniformBlockRefPtr _shadowUniformBlock; + GlfUniformBlockRefPtr _materialUniformBlock; + GlfUniformBlockRefPtr _bindlessShadowlUniformBlock; + + class _PostSurfaceShaderState; + std::unique_ptr<_PostSurfaceShaderState> _postSurfaceShaderState; + + bool _lightingUniformBlockValid; + bool _shadowUniformBlockValid; + bool _materialUniformBlockValid; + bool _postSurfaceShaderStateValid; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/Sources/OpenUSD/include/imaging/glf/simpleMaterial.h b/Sources/Glf/include/Glf/simpleMaterial.h similarity index 56% rename from Sources/OpenUSD/include/imaging/glf/simpleMaterial.h rename to Sources/Glf/include/Glf/simpleMaterial.h index 02d0fd5622..c241d179a2 100644 --- a/Sources/OpenUSD/include/imaging/glf/simpleMaterial.h +++ b/Sources/Glf/include/Glf/simpleMaterial.h @@ -26,59 +26,58 @@ /// \file glf/simpleMaterial.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/base/gf/vec4f.h" +#include +#include "Glf/api.h" +#include "Gf/vec4f.h" PXR_NAMESPACE_OPEN_SCOPE - -class GlfSimpleMaterial final { +class GlfSimpleMaterial final +{ public: - GLF_API - GlfSimpleMaterial(); - GLF_API - ~GlfSimpleMaterial(); + GLF_API + GlfSimpleMaterial(); + GLF_API + ~GlfSimpleMaterial(); - GLF_API - GfVec4f const & GetAmbient() const; - GLF_API - void SetAmbient(GfVec4f const & ambient); + GLF_API + GfVec4f const &GetAmbient() const; + GLF_API + void SetAmbient(GfVec4f const &ambient); - GLF_API - GfVec4f const & GetDiffuse() const; - GLF_API - void SetDiffuse(GfVec4f const & diffuse); + GLF_API + GfVec4f const &GetDiffuse() const; + GLF_API + void SetDiffuse(GfVec4f const &diffuse); - GLF_API - GfVec4f const & GetSpecular() const; - GLF_API - void SetSpecular(GfVec4f const & specular); + GLF_API + GfVec4f const &GetSpecular() const; + GLF_API + void SetSpecular(GfVec4f const &specular); - GLF_API - GfVec4f const & GetEmission() const; - GLF_API - void SetEmission(GfVec4f const & specular); + GLF_API + GfVec4f const &GetEmission() const; + GLF_API + void SetEmission(GfVec4f const &specular); - GLF_API - double GetShininess() const; - GLF_API - void SetShininess(double specular); + GLF_API + double GetShininess() const; + GLF_API + void SetShininess(double specular); - GLF_API - bool operator ==(GlfSimpleMaterial const & other) const; - GLF_API - bool operator !=(GlfSimpleMaterial const & other) const; + GLF_API + bool operator==(GlfSimpleMaterial const &other) const; + GLF_API + bool operator!=(GlfSimpleMaterial const &other) const; private: - GfVec4f _ambient; - GfVec4f _diffuse; - GfVec4f _specular; - GfVec4f _emission; - double _shininess; + GfVec4f _ambient; + GfVec4f _diffuse; + GfVec4f _specular; + GfVec4f _emission; + double _shininess; }; - PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/Sources/Glf/include/Glf/simpleShadowArray.h b/Sources/Glf/include/Glf/simpleShadowArray.h new file mode 100644 index 0000000000..796cf646f0 --- /dev/null +++ b/Sources/Glf/include/Glf/simpleShadowArray.h @@ -0,0 +1,150 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_SIMPLE_SHADOW_ARRAY_H +#define PXR_IMAGING_GLF_SIMPLE_SHADOW_ARRAY_H + +/// \file glf/simpleShadowArray.h + +#include +#include "Glf/api.h" +#include "Tf/declarePtrs.h" +#include "Tf/refPtr.h" +#include "Tf/weakPtr.h" +#include "Gf/matrix4d.h" +#include "Gf/vec2i.h" +#include "Gf/vec4d.h" +#include "Garch/glApi.h" + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +class GlfSimpleShadowArray : public TfRefBase, + public TfWeakBase +{ +public: + GLF_API + GlfSimpleShadowArray(); + GLF_API + ~GlfSimpleShadowArray() override; + + // Disallow copies + GlfSimpleShadowArray(const GlfSimpleShadowArray &) = delete; + GlfSimpleShadowArray &operator=(const GlfSimpleShadowArray &) = delete; + + // Returns the GL texture id of the shadow texture. + GLF_API + GLuint GetShadowMapTexture(int shadowIndex) const; + + // Returns the GL sampler id of the sampler object used to read the raw + // depth values. + GLF_API + GLuint GetShadowMapDepthSampler() const; + + // Returns the GL sampler id of the sampler object used for depth comparison + GLF_API + GLuint GetShadowMapCompareSampler() const; + + // Set the resolutions of all the shadow maps necessary. The number of + // resolutions corresponds to the number of shadow map textures necessary, + // which is currently one per shadow casting light. + GLF_API + void SetShadowMapResolutions(std::vector const &resolutions); + + // Returns the number of shadow map generation passes required, which is + // currently one per shadow map (corresponding to a shadow casting light). + GLF_API + size_t GetNumShadowMapPasses() const; + + // Returns the shadow map resolution for a given pass. + // this returns the resolution of the corresponding shadow map, + GLF_API + GfVec2i GetShadowMapSize(size_t pass) const; + + // Get/Set the view (world to shadow camera) transform to use for a given + // shadow map generation pass. + GLF_API + GfMatrix4d GetViewMatrix(size_t index) const; + GLF_API + void SetViewMatrix(size_t index, GfMatrix4d const &matrix); + + // Get/Set the projection transform to use for a given shadow map generation + // pass. + GLF_API + GfMatrix4d GetProjectionMatrix(size_t index) const; + GLF_API + void SetProjectionMatrix(size_t index, GfMatrix4d const &matrix); + + GLF_API + GfMatrix4d GetWorldToShadowMatrix(size_t index) const; + + // Bind necessary resources for a given shadow map generation pass. + GLF_API + void BeginCapture(size_t index, bool clear); + + // Unbind necssary resources after a shadow map gneration pass. + GLF_API + void EndCapture(size_t index); + + // Sets the GL texture ids of the shadow textures, as opposed to creating + // them internally with _AllocTextures(). + GLF_API + void SetTextures(std::vector textureIds); + + // Allocates the shadow samplers. + GLF_API + void AllocSamplers(); + +private: + void _AllocResources(); + void _AllocTextures(); + void _FreeResources(); + void _FreeTextures(); + bool _ShadowMapExists() const; + void _BindFramebuffer(size_t index); + void _UnbindFramebuffer(); + +private: + std::vector _resolutions; + std::vector _textures; + + std::vector _viewMatrix; + std::vector _projectionMatrix; + + GLuint _framebuffer; + + GLuint _shadowDepthSampler; + GLuint _shadowCompareSampler; + + GLuint _unbindRestoreDrawFramebuffer; + GLuint _unbindRestoreReadFramebuffer; + + GLint _unbindRestoreViewport[4]; + + bool _texturesAllocatedExternally; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/Sources/OpenUSD/include/imaging/glf/testGLContext.h b/Sources/Glf/include/Glf/testGLContext.h similarity index 57% rename from Sources/OpenUSD/include/imaging/glf/testGLContext.h rename to Sources/Glf/include/Glf/testGLContext.h index c3bf79783c..dd70f6cc37 100644 --- a/Sources/OpenUSD/include/imaging/glf/testGLContext.h +++ b/Sources/Glf/include/Glf/testGLContext.h @@ -26,12 +26,20 @@ /// \file glf/testGLContext.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/glf/glContext.h" +#include +#include "Glf/api.h" +#include "Glf/glContext.h" #include +#if (defined(__linux__) || defined(_WIN32)) && __has_include() +# define WITH_TEST_GL_CONTEXT 1 +# else // !defined(__linux__) && !defined(_WIN32) && !__has_include() +# define WITH_TEST_GL_CONTEXT 0 +#endif // defined(__linux__) || defined(_WIN32) && __has_include() + +#if WITH_TEST_GL_CONTEXT + PXR_NAMESPACE_OPEN_SCOPE class Glf_TestGLContextPrivate; @@ -42,37 +50,39 @@ typedef std::shared_ptr GlfTestGLContextSharedPtr; /// /// Testing support class for GlfGLContext. /// -class GlfTestGLContext : public GlfGLContext { +class GlfTestGLContext : public GlfGLContext +{ public: - GLF_API - static void RegisterGLContextCallbacks(); + GLF_API + static void RegisterGLContextCallbacks(); - // GlfGLContext overrides - GLF_API - virtual bool IsValid() const; + // GlfGLContext overrides + GLF_API + virtual bool IsValid() const; - GLF_API - static GlfTestGLContextSharedPtr Create( GlfTestGLContextSharedPtr const & share ); + GLF_API + static GlfTestGLContextSharedPtr Create(GlfTestGLContextSharedPtr const &share); protected: - // GlfGLContext overrides - GLF_API - virtual void _MakeCurrent(); - GLF_API - virtual bool _IsSharing(const GlfGLContextSharedPtr& rhs) const; - GLF_API - virtual bool _IsEqual(const GlfGLContextSharedPtr& rhs) const; + // GlfGLContext overrides + GLF_API + virtual void _MakeCurrent(); + GLF_API + virtual bool _IsSharing(const GlfGLContextSharedPtr &rhs) const; + GLF_API + virtual bool _IsEqual(const GlfGLContextSharedPtr &rhs) const; private: - GlfTestGLContext(Glf_TestGLContextPrivate const * context); + GlfTestGLContext(Glf_TestGLContextPrivate const *context); - friend class GlfTestGLContextRegistrationInterface; + friend class GlfTestGLContextRegistrationInterface; private: - Glf_TestGLContextPrivate * _context; + Glf_TestGLContextPrivate *_context; }; - PXR_NAMESPACE_CLOSE_SCOPE -#endif // PXR_IMAGING_GLF_TEST_GLCONTEXT_H +#endif // WITH_TEST_GL_CONTEXT + +#endif // PXR_IMAGING_GLF_TEST_GLCONTEXT_H diff --git a/Sources/Glf/include/Glf/texture.h b/Sources/Glf/include/Glf/texture.h new file mode 100644 index 0000000000..8c6fbd4a56 --- /dev/null +++ b/Sources/Glf/include/Glf/texture.h @@ -0,0 +1,172 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_IMAGING_GLF_TEXTURE_H +#define PXR_IMAGING_GLF_TEXTURE_H + +/// \file glf/texture.h + +#include +#include "Glf/api.h" +#include "Hio/image.h" +#include "Tf/declarePtrs.h" +#include "Tf/refPtr.h" +#include "Tf/staticTokens.h" +#include "Tf/weakPtr.h" +#include "Vt/dictionary.h" + +#include "Garch/glApi.h" + +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +#define GLF_TEXTURE_TOKENS \ + (texels)(layout) + +TF_DECLARE_PUBLIC_TOKENS(GlfTextureTokens, GLF_API, GLF_TEXTURE_TOKENS); + +TF_DECLARE_WEAK_AND_REF_PTRS(GlfTexture); + +/// \class GlfTexture +/// +/// Represents a texture object in Glf. +/// +/// A texture is typically defined by reading texture image data from an image +/// file but a texture might also represent an attachment of a draw target. +/// +class GlfTexture : public TfRefBase, public TfWeakBase +{ +public: + /// \class Binding + /// + /// A texture has one or more bindings which describe how the different + /// aspects of the texture should be bound in order to allow shader + /// access. Most textures will have a single binding for the role + /// "texels", but some textures might need multiple bindings, e.g. a + /// ptexTexture will have an additional binding for the role "layout". + /// + struct Binding + { + Binding(TfToken name, TfToken role, GLenum target, + GLuint textureId, GLuint samplerId) + : name(name), role(role), target(target), textureId(textureId), samplerId(samplerId) {} + + TfToken name; + TfToken role; + GLenum target; + GLuint textureId; + GLuint samplerId; + }; + typedef std::vector BindingVector; + + GLF_API + virtual ~GlfTexture() = 0; + + // Disallow copies + GlfTexture(const GlfTexture &) = delete; + GlfTexture &operator=(const GlfTexture &) = delete; + + /// Returns the bindings to use this texture for the shader resource + /// named \a identifier. If \a samplerId is specified, the bindings + /// returned will use this samplerId for resources which can be sampled. + virtual BindingVector GetBindings(TfToken const &identifier, + GLuint samplerId = 0) = 0; + + /// Returns the OpenGl texture name for the texture. + virtual GLuint GetGlTextureName() = 0; + + /// Amount of memory used to store the texture + GLF_API + size_t GetMemoryUsed() const; + + /// Amount of memory the user wishes to allocate to the texture + GLF_API + size_t GetMemoryRequested() const; + + /// Specify the amount of memory the user wishes to allocate to the texture + GLF_API + void SetMemoryRequested(size_t targetMemory); + + virtual VtDictionary GetTextureInfo(bool forceLoad) = 0; + + GLF_API + virtual bool IsMinFilterSupported(GLenum filter); + + GLF_API + virtual bool IsMagFilterSupported(GLenum filter); + + /// static reporting function + GLF_API + static size_t GetTextureMemoryAllocated(); + + /// Returns an identifier that can be used to determine when the + /// contents of this texture (i.e. its image data) has changed. + /// + /// The contents of most textures will be immutable for the lifetime + /// of the texture. However, the contents of the texture attachments + /// of a draw target change when the draw target is updated. + GLF_API + size_t GetContentsID() const; + + GLF_API + HioImage::ImageOriginLocation GetOriginLocation() const; + + GLF_API + bool IsOriginLowerLeft() const; + +protected: + GLF_API + GlfTexture(); + + GLF_API + GlfTexture(HioImage::ImageOriginLocation originLocation); + + GLF_API + void _SetMemoryUsed(size_t size); + + GLF_API + virtual void _OnMemoryRequestedDirty(); + + GLF_API + void _UpdateContentsID(); + +private: + size_t _memoryUsed; + size_t _memoryRequested; + size_t _contentsID; + HioImage::ImageOriginLocation _originLocation; +}; + +class GlfTextureFactoryBase : public TfType::FactoryBase +{ +public: + virtual GlfTextureRefPtr New(const TfToken &texturePath, + HioImage::ImageOriginLocation originLocation) const = 0; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // PXR_IMAGING_GLF_TEXTURE_H diff --git a/Sources/OpenUSD/include/imaging/glf/uniformBlock.h b/Sources/Glf/include/Glf/uniformBlock.h similarity index 62% rename from Sources/OpenUSD/include/imaging/glf/uniformBlock.h rename to Sources/Glf/include/Glf/uniformBlock.h index cce98b3b84..0eba4c34c6 100644 --- a/Sources/OpenUSD/include/imaging/glf/uniformBlock.h +++ b/Sources/Glf/include/Glf/uniformBlock.h @@ -26,17 +26,16 @@ /// \file glf/uniformBlock.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/garch/glApi.h" -#include "pxr/base/tf/declarePtrs.h" -#include "pxr/base/tf/refBase.h" -#include "pxr/base/tf/weakBase.h" +#include +#include "Glf/api.h" +#include "Garch/glApi.h" +#include "Tf/declarePtrs.h" +#include "Tf/refBase.h" +#include "Tf/weakBase.h" #include PXR_NAMESPACE_OPEN_SCOPE - TF_DECLARE_WEAK_AND_REF_PTRS(GlfUniformBlock); TF_DECLARE_WEAK_PTRS(GlfBindingMap); @@ -44,37 +43,36 @@ TF_DECLARE_WEAK_PTRS(GlfBindingMap); /// /// Manages a GL uniform buffer object. /// -class GlfUniformBlock : public TfRefBase, public TfWeakBase { +class GlfUniformBlock : public TfRefBase, public TfWeakBase +{ public: + /// Returns a new instance. + GLF_API + static GlfUniformBlockRefPtr New(char const *label = nullptr); - /// Returns a new instance. - GLF_API - static GlfUniformBlockRefPtr New(char const *label = nullptr); + GLF_API + virtual ~GlfUniformBlock(); - GLF_API - virtual ~GlfUniformBlock(); + /// Binds the uniform buffer using a bindingMap and identifier. + GLF_API + void Bind(GlfBindingMapPtr const &bindingMap, + std::string const &identifier); - /// Binds the uniform buffer using a bindingMap and identifier. - GLF_API - void Bind(GlfBindingMapPtr const & bindingMap, - std::string const & identifier); + /// Updates the content of the uniform buffer. If the size + /// is different, the buffer will be reallocated. + GLF_API + void Update(const void *data, int size); - /// Updates the content of the uniform buffer. If the size - /// is different, the buffer will be reallocated. - GLF_API - void Update(const void *data, int size); - protected: - GLF_API - GlfUniformBlock(char const *label); + GLF_API + GlfUniformBlock(char const *label); private: - GLuint _buffer; - int _size; - std::string _debugLabel; + GLuint _buffer; + int _size; + std::string _debugLabel; }; - PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/Sources/OpenUSD/include/imaging/glf/utils.h b/Sources/Glf/include/Glf/utils.h similarity index 90% rename from Sources/OpenUSD/include/imaging/glf/utils.h rename to Sources/Glf/include/Glf/utils.h index a43b20fc2b..6a51d305f9 100644 --- a/Sources/OpenUSD/include/imaging/glf/utils.h +++ b/Sources/Glf/include/Glf/utils.h @@ -26,10 +26,10 @@ /// \file glf/utils.h -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/garch/glApi.h" -#include "pxr/imaging/hio/types.h" +#include +#include "Glf/api.h" +#include "Garch/glApi.h" +#include "Hio/types.h" #include @@ -39,16 +39,16 @@ PXR_NAMESPACE_OPEN_SCOPE /// /// Returns the number of elements (channels) in a given GL enum format. /// -/// Supported formats are : GL_DEPTH_COMPONENT, GL_COLOR_INDEX, GL_ALPHA, +/// Supported formats are : GL_DEPTH_COMPONENT, GL_COLOR_INDEX, GL_ALPHA, /// GL_RED, GL_LUMINANCE, GL_RG, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA -GLF_API +GLF_API int GlfGetNumElements(GLenum format); /// Byte size of a GL type. /// /// Returns the size in bytes of a given GL type. /// -/// Supported types are : GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, +/// Supported types are : GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, /// GL_SHORT, GL_FLOAT, GL_DOUBLE GLF_API int GlfGetElementSize(GLenum type); @@ -57,21 +57,20 @@ int GlfGetElementSize(GLenum type); /// /// Returns the HioFormat for the given GL format and GL type /// -/// Supported formats are : GL_DEPTH_COMPONENT, GL_COLOR_INDEX, GL_ALPHA, +/// Supported formats are : GL_DEPTH_COMPONENT, GL_COLOR_INDEX, GL_ALPHA, /// GL_RED, GL_LUMINANCE, GL_RG, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA /// -/// Supported types are : GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, +/// Supported types are : GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, /// GL_SHORT, GL_FLOAT, GL_DOUBLE GLF_API HioFormat GlfGetHioFormat(GLenum glFormat, GLenum glType, bool isSRGB); - /// Checks the valitidy of a GL framebuffer /// /// True if the currently bound GL framebuffer is valid and can be bound /// or returns the cause of the problem GLF_API -bool GlfCheckGLFrameBufferStatus(GLuint target, std::string * reason); +bool GlfCheckGLFrameBufferStatus(GLuint target, std::string *reason); PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/info.cpp b/Sources/Glf/info.cpp similarity index 54% rename from Sources/OpenUSD/imaging/glf/info.cpp rename to Sources/Glf/info.cpp index 3394d2c700..bbbdef4e32 100644 --- a/Sources/OpenUSD/imaging/glf/info.cpp +++ b/Sources/Glf/info.cpp @@ -24,12 +24,12 @@ // info.cpp // -#include "pxr/imaging/garch/glApi.h" +#include "Garch/glApi.h" -#include "pxr/imaging/glf/info.h" -#include "pxr/imaging/glf/glContext.h" +#include "Glf/info.h" +#include "Glf/glContext.h" -#include "pxr/base/tf/stringUtils.h" +#include "Tf/stringUtils.h" #include #include @@ -37,7 +37,6 @@ PXR_NAMESPACE_OPEN_SCOPE - using std::set; using std::string; using std::vector; @@ -45,39 +44,40 @@ using std::vector; static set Glf_BuildAvailableExtensions() { - GlfSharedGLContextScopeHolder sharedContextScopeHolder; + GlfSharedGLContextScopeHolder sharedContextScopeHolder; - set availableExtensions; + set availableExtensions; - // Get the available extensions from OpenGL if we haven't yet. - if (const char *extensions = (const char*) glGetString(GL_EXTENSIONS)) { - const vector extensionsList = TfStringTokenize(extensions); - for (std::string const& extension : extensionsList) { - availableExtensions.insert(extension); - } + // Get the available extensions from OpenGL if we haven't yet. + if (const char *extensions = (const char *)glGetString(GL_EXTENSIONS)) + { + const vector extensionsList = TfStringTokenize(extensions); + for (std::string const &extension : extensionsList) + { + availableExtensions.insert(extension); } - return availableExtensions; + } + return availableExtensions; } -bool -GlfHasExtensions(string const & queryExtensions) +bool GlfHasExtensions(string const &queryExtensions) { - static set availableExtensions = Glf_BuildAvailableExtensions(); + static set availableExtensions = Glf_BuildAvailableExtensions(); - // Tokenize the queried extensions. - const vector extensionsList = TfStringTokenize(queryExtensions); + // Tokenize the queried extensions. + const vector extensionsList = TfStringTokenize(queryExtensions); - // Return false if any queried extension is not available. - for (std::string const& extension : extensionsList) { - if (!availableExtensions.count(extension)) { - return false; - } + // Return false if any queried extension is not available. + for (std::string const &extension : extensionsList) + { + if (!availableExtensions.count(extension)) + { + return false; } + } - // All queried extensions were found. - return true; + // All queried extensions were found. + return true; } - PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/Glf/simpleLight.cpp b/Sources/Glf/simpleLight.cpp new file mode 100644 index 0000000000..1ff62c01de --- /dev/null +++ b/Sources/Glf/simpleLight.cpp @@ -0,0 +1,358 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +/// \file simpleLight.cpp + +#include "Glf/simpleLight.h" + +#include "Garch/glApi.h" + +PXR_NAMESPACE_OPEN_SCOPE + +GlfSimpleLight::GlfSimpleLight(GfVec4f const &position) : _ambient(0.2, 0.2, 0.2, 1.0), + _diffuse(1.0, 1.0, 1.0, 1.0), + _specular(1.0, 1.0, 1.0, 1.0), + _position(position[0], position[1], position[2], 1.0), + _spotDirection(0.0, 0.0, -1.0), + _spotCutoff(180.0), + _spotFalloff(0.0), + _attenuation(1.0, 0.0, 0.0), + _isCameraSpaceLight(false), + _hasIntensity(true), + _hasShadow(false), + _shadowResolution(512), + _shadowBias(0.0), + _shadowBlur(0.0), + _shadowIndexStart(0), + _shadowIndexEnd(0), + _transform(GfMatrix4d().SetIdentity()), + _shadowMatrices(std::vector(1, GfMatrix4d().SetIdentity())), + _isDomeLight(false), + _id() +{ +} + +GlfSimpleLight::~GlfSimpleLight() = default; + +GfMatrix4d const & +GlfSimpleLight::GetTransform() const +{ + return _transform; +} + +void GlfSimpleLight::SetTransform(GfMatrix4d const &mat) +{ + _transform = mat; +} + +GfVec4f const & +GlfSimpleLight::GetAmbient() const +{ + return _ambient; +} + +void GlfSimpleLight::SetAmbient(GfVec4f const &ambient) +{ + _ambient = ambient; +} + +GfVec4f const & +GlfSimpleLight::GetDiffuse() const +{ + return _diffuse; +} + +void GlfSimpleLight::SetDiffuse(GfVec4f const &diffuse) +{ + _diffuse = diffuse; +} + +GfVec4f const & +GlfSimpleLight::GetSpecular() const +{ + return _specular; +} + +void GlfSimpleLight::SetSpecular(GfVec4f const &specular) +{ + _specular = specular; +} + +GfVec4f const & +GlfSimpleLight::GetPosition() const +{ + return _position; +} + +void GlfSimpleLight::SetPosition(GfVec4f const &position) +{ + _position = position; +} + +GfVec3f const & +GlfSimpleLight::GetSpotDirection() const +{ + return _spotDirection; +} + +void GlfSimpleLight::SetSpotDirection(GfVec3f const &spotDirection) +{ + _spotDirection = spotDirection; +} + +float const & +GlfSimpleLight::GetSpotCutoff() const +{ + return _spotCutoff; +} + +void GlfSimpleLight::SetSpotCutoff(float const &spotCutoff) +{ + _spotCutoff = spotCutoff; +} + +float const & +GlfSimpleLight::GetSpotFalloff() const +{ + return _spotFalloff; +} + +void GlfSimpleLight::SetSpotFalloff(float const &spotFalloff) +{ + _spotFalloff = spotFalloff; +} + +GfVec3f const & +GlfSimpleLight::GetAttenuation() const +{ + return _attenuation; +} + +void GlfSimpleLight::SetAttenuation(GfVec3f const &attenuation) +{ + _attenuation = attenuation; +} + +void GlfSimpleLight::SetHasIntensity(bool hasIntensity) +{ + _hasIntensity = hasIntensity; +} + +bool GlfSimpleLight::HasIntensity() const +{ + return _hasIntensity; +} + +bool GlfSimpleLight::HasShadow() const +{ + return _hasShadow; +} + +void GlfSimpleLight::SetHasShadow(bool hasShadow) +{ + _hasShadow = hasShadow; +} + +int GlfSimpleLight::GetShadowResolution() const +{ + return _shadowResolution; +} + +void GlfSimpleLight::SetShadowResolution(int resolution) +{ + _shadowResolution = resolution; +} + +float GlfSimpleLight::GetShadowBias() const +{ + return _shadowBias; +} + +void GlfSimpleLight::SetShadowBias(float bias) +{ + _shadowBias = bias; +} + +float GlfSimpleLight::GetShadowBlur() const +{ + return _shadowBlur; +} + +void GlfSimpleLight::SetShadowBlur(float blur) +{ + _shadowBlur = blur; +} + +int GlfSimpleLight::GetShadowIndexStart() const +{ + return _shadowIndexStart; +} + +void GlfSimpleLight::SetShadowIndexStart(int shadowStart) +{ + _shadowIndexStart = shadowStart; +} + +int GlfSimpleLight::GetShadowIndexEnd() const +{ + return _shadowIndexEnd; +} + +void GlfSimpleLight::SetShadowIndexEnd(int shadowEnd) +{ + _shadowIndexEnd = shadowEnd; +} + +std::vector const & +GlfSimpleLight::GetShadowMatrices() const +{ + return _shadowMatrices; +} + +void GlfSimpleLight::SetShadowMatrices(std::vector const &matrices) +{ + _shadowMatrices = matrices; +} + +bool GlfSimpleLight::IsCameraSpaceLight() const +{ + return _isCameraSpaceLight; +} + +void GlfSimpleLight::SetIsCameraSpaceLight(bool isCameraSpaceLight) +{ + _isCameraSpaceLight = isCameraSpaceLight; +} + +SdfPath const & +GlfSimpleLight::GetID() const +{ + return _id; +} + +void GlfSimpleLight::SetID(SdfPath const &id) +{ + _id = id; +} + +bool GlfSimpleLight::IsDomeLight() const +{ + return _isDomeLight; +} + +void GlfSimpleLight::SetIsDomeLight(bool isDomeLight) +{ + _isDomeLight = isDomeLight; +} + +const SdfAssetPath & +GlfSimpleLight::GetDomeLightTextureFile() const +{ + return _domeLightTextureFile; +} + +void GlfSimpleLight::SetDomeLightTextureFile(const SdfAssetPath &path) +{ + _domeLightTextureFile = path; +} + +TfToken const & +GlfSimpleLight::GetPostSurfaceIdentifier() const +{ + return _postSurfaceIdentifier; +} + +std::string const & +GlfSimpleLight::GetPostSurfaceShaderSource() const +{ + return _postSurfaceShaderSource; +} + +VtUCharArray const & +GlfSimpleLight::GetPostSurfaceShaderParams() const +{ + return _postSurfaceShaderParams; +} + +void GlfSimpleLight::SetPostSurfaceParams(TfToken const &identifier, + std::string const &shaderSource, + VtUCharArray const &shaderParams) +{ + _postSurfaceIdentifier = identifier; + _postSurfaceShaderSource = shaderSource; + _postSurfaceShaderParams = shaderParams; +} + +// -------------------------------------------------------------------------- // +// VtValue requirements +// -------------------------------------------------------------------------- // + +bool GlfSimpleLight::operator==(const GlfSimpleLight &other) const +{ + return _ambient == other._ambient && _diffuse == other._diffuse && _specular == other._specular && _position == other._position && _spotDirection == other._spotDirection && _spotCutoff == other._spotCutoff && _spotFalloff == other._spotFalloff && _attenuation == other._attenuation && _hasIntensity == other._hasIntensity && _hasShadow == other._hasShadow && _shadowResolution == other._shadowResolution && _shadowBias == other._shadowBias && _shadowBlur == other._shadowBlur && _shadowIndexStart == other._shadowIndexStart && _shadowIndexEnd == other._shadowIndexEnd && _transform == other._transform && _shadowMatrices == other._shadowMatrices && _isCameraSpaceLight == other._isCameraSpaceLight && _isDomeLight == other._isDomeLight && _domeLightTextureFile == other._domeLightTextureFile && _postSurfaceIdentifier == other._postSurfaceIdentifier && _postSurfaceShaderSource == other._postSurfaceShaderSource && _postSurfaceShaderParams == other._postSurfaceShaderParams && _id == other._id; +} + +bool GlfSimpleLight::operator!=(const GlfSimpleLight &other) const +{ + return !(*this == other); +} + +std::ostream &operator<<(std::ostream &out, const GlfSimpleLight &v) +{ + out << v._ambient + << v._diffuse + << v._specular + << v._position + << v._spotDirection + << v._spotCutoff + << v._spotFalloff + << v._attenuation + << v._hasIntensity + << v._hasShadow + << v._shadowResolution + << v._shadowBias + << v._shadowBlur + << v._shadowIndexStart + << v._shadowIndexEnd + << v._transform + << v._isCameraSpaceLight + << v._isDomeLight + << v._domeLightTextureFile + << v._postSurfaceIdentifier + << v._postSurfaceShaderSource + << v._postSurfaceShaderParams + << v._id; + for (auto const &m : v._shadowMatrices) + { + out << m; + } + return out; +} + +std::ostream & +operator<<(std::ostream &out, const GlfSimpleLightVector &pv) +{ + return out; +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/simpleLightingContext.cpp b/Sources/Glf/simpleLightingContext.cpp new file mode 100644 index 0000000000..2b6210c2b4 --- /dev/null +++ b/Sources/Glf/simpleLightingContext.cpp @@ -0,0 +1,792 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +/// \file simpleLightingContext.cpp + +#include "Garch/glApi.h" + +#include "Glf/simpleLightingContext.h" +#include "Glf/bindingMap.h" +#include "Glf/debugCodes.h" +#include "Glf/diagnostic.h" +#include "Glf/simpleLight.h" +#include "Glf/simpleMaterial.h" +#include "Glf/uniformBlock.h" + +#include "Hio/glslfx.h" + +#include "Arch/hash.h" +#include "Arch/pragmas.h" +#include "Tf/diagnostic.h" +#include "Tf/stringUtils.h" +#include "Tf/staticData.h" +#include "Tf/staticTokens.h" + +#include "Trace/traceImpl.h" + +#include +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + ((lightingUB, "Lighting"))((shadowUB, "Shadow"))((materialUB, "Material"))((postSurfaceShaderUB, "PostSurfaceShaderParams"))((shadowCompareTextures, "shadowCompareTextures"))); + +/* static */ +GlfSimpleLightingContextRefPtr +GlfSimpleLightingContext::New() +{ + return TfCreateRefPtr(new This()); +} + +GlfSimpleLightingContext::GlfSimpleLightingContext() : _shadows(TfCreateRefPtr(new GlfSimpleShadowArray())), + _worldToViewMatrix(1.0), + _projectionMatrix(1.0), + _sceneAmbient(0.01, 0.01, 0.01, 1.0), + _useLighting(false), + _useShadows(false), + _useColorMaterialDiffuse(false), + _lightingUniformBlockValid(false), + _shadowUniformBlockValid(false), + _materialUniformBlockValid(false), + _postSurfaceShaderStateValid(false) +{ +} + +GlfSimpleLightingContext::~GlfSimpleLightingContext() +{ +} + +void GlfSimpleLightingContext::SetLights(GlfSimpleLightVector const &lights) +{ + _lights = lights; + _lightingUniformBlockValid = false; + _shadowUniformBlockValid = false; + _postSurfaceShaderStateValid = false; + + int numLights = GetNumLightsUsed(); + + _useShadows = false; + for (int i = 0; i < numLights; ++i) + { + if (_lights[i].HasShadow()) + { + _useShadows = true; + break; + } + } +} + +const GlfSimpleLightVector & +GlfSimpleLightingContext::GetLights() const +{ + return _lights; +} + +int GlfSimpleLightingContext::GetNumLightsUsed() const +{ + return (int)_lights.size(); +} + +int GlfSimpleLightingContext::ComputeNumShadowsUsed() const +{ + int numShadows = 0; + for (auto const &light : _lights) + { + if (light.HasShadow() && numShadows <= light.GetShadowIndexEnd()) + { + numShadows = light.GetShadowIndexEnd() + 1; + } + } + return numShadows; +} + +void GlfSimpleLightingContext::SetShadows(GlfSimpleShadowArrayRefPtr const &shadows) +{ + _shadows = shadows; + _shadowUniformBlockValid = false; +} + +GlfSimpleShadowArrayRefPtr const & +GlfSimpleLightingContext::GetShadows() const +{ + return _shadows; +} + +void GlfSimpleLightingContext::SetMaterial(GlfSimpleMaterial const &material) +{ + if (_material != material) + { + _material = material; + _materialUniformBlockValid = false; + } +} + +GlfSimpleMaterial const & +GlfSimpleLightingContext::GetMaterial() const +{ + return _material; +} + +void GlfSimpleLightingContext::SetSceneAmbient(GfVec4f const &sceneAmbient) +{ + if (_sceneAmbient != sceneAmbient) + { + _sceneAmbient = sceneAmbient; + _materialUniformBlockValid = false; + } +} + +GfVec4f const & +GlfSimpleLightingContext::GetSceneAmbient() const +{ + return _sceneAmbient; +} + +void GlfSimpleLightingContext::SetCamera(GfMatrix4d const &worldToViewMatrix, + GfMatrix4d const &projectionMatrix) +{ + if (_worldToViewMatrix != worldToViewMatrix) + { + _worldToViewMatrix = worldToViewMatrix; + _lightingUniformBlockValid = false; + _shadowUniformBlockValid = false; + } + _projectionMatrix = projectionMatrix; +} + +void GlfSimpleLightingContext::SetUseLighting(bool val) +{ + if (_useLighting != val) + { + _useLighting = val; + _lightingUniformBlockValid = false; + } +} + +bool GlfSimpleLightingContext::GetUseLighting() const +{ + return _useLighting; +} + +bool GlfSimpleLightingContext::GetUseShadows() const +{ + return _useShadows; +} + +void GlfSimpleLightingContext::SetUseColorMaterialDiffuse(bool val) +{ + if (_useColorMaterialDiffuse != val) + { + _lightingUniformBlockValid = false; + _useColorMaterialDiffuse = val; + } +} + +bool GlfSimpleLightingContext::GetUseColorMaterialDiffuse() const +{ + return _useColorMaterialDiffuse; +} + +void GlfSimpleLightingContext::InitUniformBlockBindings( + GlfBindingMapPtr const &bindingMap) const +{ + // populate uniform bindings (XXX: need better API) + bindingMap->GetUniformBinding(_tokens->lightingUB); + bindingMap->GetUniformBinding(_tokens->shadowUB); + bindingMap->GetUniformBinding(_tokens->materialUB); + bindingMap->GetUniformBinding(_tokens->postSurfaceShaderUB); +} + +void GlfSimpleLightingContext::InitSamplerUnitBindings( + GlfBindingMapPtr const &bindingMap) const +{ + size_t const numShadows = _shadows->GetNumShadowMapPasses(); + for (size_t i = 0; i < numShadows; ++i) + { + bindingMap->GetSamplerUnit( + TfStringPrintf("%s[%zd]", + _tokens->shadowCompareTextures.GetText(), i)); + } +} + +inline void +setVec3(float *dst, GfVec3f const &vec) +{ + dst[0] = vec[0]; + dst[1] = vec[1]; + dst[2] = vec[2]; +} + +inline static void +setVec4(float *dst, GfVec4f const &vec) +{ + dst[0] = vec[0]; + dst[1] = vec[1]; + dst[2] = vec[2]; + dst[3] = vec[3]; +} + +inline static void +setMatrix(float *dst, GfMatrix4d const &mat) +{ + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + dst[i * 4 + j] = (float)mat[i][j]; +} + +void GlfSimpleLightingContext::BindUniformBlocks(GlfBindingMapPtr const &bindingMap) +{ + GLF_GROUP_FUNCTION(); + + if (!_lightingUniformBlock) + _lightingUniformBlock = GlfUniformBlock::New("_lightingUniformBlock"); + if (!_shadowUniformBlock) + _shadowUniformBlock = GlfUniformBlock::New("_shadowUniformBlock"); + if (!_materialUniformBlock) + _materialUniformBlock = GlfUniformBlock::New("_materialUniformBlock"); + + bool shadowExists = false; + if ((!_lightingUniformBlockValid || + !_shadowUniformBlockValid) && + _lights.size() > 0) + { + int numLights = GetNumLightsUsed(); + int numShadows = ComputeNumShadowsUsed(); + + // 16byte aligned + struct LightSource + { + float position[4]; + float ambient[4]; + float diffuse[4]; + float specular[4]; + float spotDirection[4]; + float spotCutoff; + float spotFalloff; + float padding[2]; + float attenuation[4]; + float worldToLightTransform[16]; + int32_t shadowIndexStart; + int32_t shadowIndexEnd; + int32_t hasShadow; + int32_t isIndirectLight; + }; + + struct Lighting + { + int32_t useLighting; + int32_t useColorMaterialDiffuse; + int32_t padding[2]; + ARCH_PRAGMA_PUSH + ARCH_PRAGMA_ZERO_SIZED_STRUCT + LightSource lightSource[0]; + ARCH_PRAGMA_POP + }; + + // 16byte aligned + struct ShadowMatrix + { + float viewToShadowMatrix[16]; + float shadowToViewMatrix[16]; + float blur; + float bias; + float padding[2]; + }; + + struct Shadow + { + ARCH_PRAGMA_PUSH + ARCH_PRAGMA_ZERO_SIZED_STRUCT + ShadowMatrix shadow[0]; + ARCH_PRAGMA_POP + }; + + size_t lightingSize = sizeof(Lighting) + sizeof(LightSource) * numLights; + size_t shadowSize = sizeof(ShadowMatrix) * numShadows; + Lighting *lightingData = (Lighting *)alloca(lightingSize); + Shadow *shadowData = (Shadow *)alloca(shadowSize); + memset(shadowData, 0, shadowSize); + memset(lightingData, 0, lightingSize); + + GfMatrix4d viewToWorldMatrix = _worldToViewMatrix.GetInverse(); + + lightingData->useLighting = _useLighting; + lightingData->useColorMaterialDiffuse = _useColorMaterialDiffuse; + + for (int i = 0; _useLighting && i < numLights; ++i) + { + GlfSimpleLight const &light = _lights[i]; + + setVec4(lightingData->lightSource[i].position, + light.GetPosition() * _worldToViewMatrix); + setVec4(lightingData->lightSource[i].diffuse, light.GetDiffuse()); + setVec4(lightingData->lightSource[i].ambient, light.GetAmbient()); + setVec4(lightingData->lightSource[i].specular, light.GetSpecular()); + setVec3(lightingData->lightSource[i].spotDirection, + _worldToViewMatrix.TransformDir(light.GetSpotDirection())); + setVec3(lightingData->lightSource[i].attenuation, + light.GetAttenuation()); + lightingData->lightSource[i].spotCutoff = light.GetSpotCutoff(); + lightingData->lightSource[i].spotFalloff = light.GetSpotFalloff(); + setMatrix(lightingData->lightSource[i].worldToLightTransform, + light.GetTransform().GetInverse()); + lightingData->lightSource[i].hasShadow = light.HasShadow(); + lightingData->lightSource[i].isIndirectLight = light.IsDomeLight(); + + if (lightingData->lightSource[i].hasShadow) + { + int shadowIndexStart = light.GetShadowIndexStart(); + lightingData->lightSource[i].shadowIndexStart = + shadowIndexStart; + int shadowIndexEnd = light.GetShadowIndexEnd(); + lightingData->lightSource[i].shadowIndexEnd = shadowIndexEnd; + + for (int shadowIndex = shadowIndexStart; + shadowIndex <= shadowIndexEnd; ++shadowIndex) + { + GfMatrix4d viewToShadowMatrix = viewToWorldMatrix * + _shadows->GetWorldToShadowMatrix(shadowIndex); + GfMatrix4d shadowToViewMatrix = + viewToShadowMatrix.GetInverse(); + + shadowData->shadow[shadowIndex].bias = light.GetShadowBias(); + shadowData->shadow[shadowIndex].blur = light.GetShadowBlur(); + + setMatrix( + shadowData->shadow[shadowIndex].viewToShadowMatrix, + viewToShadowMatrix); + setMatrix( + shadowData->shadow[shadowIndex].shadowToViewMatrix, + shadowToViewMatrix); + } + + shadowExists = true; + } + } + + _lightingUniformBlock->Update(lightingData, lightingSize); + _lightingUniformBlockValid = true; + + if (shadowExists) + { + _shadowUniformBlock->Update(shadowData, shadowSize); + _shadowUniformBlockValid = true; + } + } + + _lightingUniformBlock->Bind(bindingMap, _tokens->lightingUB); + + if (shadowExists) + { + _shadowUniformBlock->Bind(bindingMap, _tokens->shadowUB); + } + + if (!_materialUniformBlockValid) + { + // has to be matched with the definition of simpleLightingShader.glslfx + struct Material + { + float ambient[4]; + float diffuse[4]; + float specular[4]; + float emission[4]; + float sceneColor[4]; // XXX: should be separated? + float shininess; + float padding[3]; + } materialData; + + memset(&materialData, 0, sizeof(materialData)); + + setVec4(materialData.ambient, _material.GetAmbient()); + setVec4(materialData.diffuse, _material.GetDiffuse()); + setVec4(materialData.specular, _material.GetSpecular()); + setVec4(materialData.emission, _material.GetEmission()); + materialData.shininess = _material.GetShininess(); + setVec4(materialData.sceneColor, _sceneAmbient); + + _materialUniformBlock->Update(&materialData, sizeof(materialData)); + _materialUniformBlockValid = true; + } + + _materialUniformBlock->Bind(bindingMap, _tokens->materialUB); + + _BindPostSurfaceShaderParams(bindingMap); +} + +void GlfSimpleLightingContext::BindSamplers(GlfBindingMapPtr const &bindingMap) +{ + size_t const numShadows = _shadows->GetNumShadowMapPasses(); + for (size_t i = 0; i < numShadows; ++i) + { + std::string samplerName = + TfStringPrintf("%s[%zd]", + _tokens->shadowCompareTextures.GetText(), i); + int shadowSampler = bindingMap->GetSamplerUnit(samplerName); + + glActiveTexture(GL_TEXTURE0 + shadowSampler); + glBindTexture(GL_TEXTURE_2D, _shadows->GetShadowMapTexture(i)); + glBindSampler(shadowSampler, _shadows->GetShadowMapCompareSampler()); + } + + glActiveTexture(GL_TEXTURE0); +} + +void GlfSimpleLightingContext::UnbindSamplers(GlfBindingMapPtr const &bindingMap) +{ + size_t const numShadows = _shadows->GetNumShadowMapPasses(); + for (size_t i = 0; i < numShadows; ++i) + { + std::string samplerName = + TfStringPrintf("%s[%zd]", + _tokens->shadowCompareTextures.GetText(), i); + int shadowSampler = bindingMap->GetSamplerUnit(samplerName); + + glActiveTexture(GL_TEXTURE0 + shadowSampler); + glBindTexture(GL_TEXTURE_2D, 0); + glBindSampler(shadowSampler, 0); + } + + glActiveTexture(GL_TEXTURE0); +} + +void GlfSimpleLightingContext::SetStateFromOpenGL() +{ + // import classic GL light's parameters into shaded lights + SetUseLighting(glIsEnabled(GL_LIGHTING) == GL_TRUE); + + GfMatrix4d worldToViewMatrix; + glGetDoublev(GL_MODELVIEW_MATRIX, worldToViewMatrix.GetArray()); + GfMatrix4d viewToWorldMatrix = worldToViewMatrix.GetInverse(); + + GLint nLights = 0; + glGetIntegerv(GL_MAX_LIGHTS, &nLights); + + GlfSimpleLightVector lights; + lights.reserve(nLights); + + GlfSimpleLight light; + for (int i = 0; i < nLights; ++i) + { + int lightName = GL_LIGHT0 + i; + if (glIsEnabled(lightName)) + { + GLfloat position[4], color[4]; + + glGetLightfv(lightName, GL_POSITION, position); + light.SetPosition(GfVec4f(position) * viewToWorldMatrix); + + glGetLightfv(lightName, GL_AMBIENT, color); + light.SetAmbient(GfVec4f(color)); + + glGetLightfv(lightName, GL_DIFFUSE, color); + light.SetDiffuse(GfVec4f(color)); + + glGetLightfv(lightName, GL_SPECULAR, color); + light.SetSpecular(GfVec4f(color)); + + GLfloat spotDirection[3]; + glGetLightfv(lightName, GL_SPOT_DIRECTION, spotDirection); + light.SetSpotDirection( + viewToWorldMatrix.TransformDir(GfVec3f(spotDirection))); + + GLfloat floatValue; + + glGetLightfv(lightName, GL_SPOT_CUTOFF, &floatValue); + light.SetSpotCutoff(floatValue); + + glGetLightfv(lightName, GL_SPOT_EXPONENT, &floatValue); + light.SetSpotFalloff(floatValue); + + GfVec3f attenuation; + glGetLightfv(lightName, GL_CONSTANT_ATTENUATION, &floatValue); + attenuation[0] = floatValue; + + glGetLightfv(lightName, GL_LINEAR_ATTENUATION, &floatValue); + attenuation[1] = floatValue; + + glGetLightfv(lightName, GL_QUADRATIC_ATTENUATION, &floatValue); + attenuation[2] = floatValue; + + light.SetAttenuation(attenuation); + + lights.push_back(light); + } + } + + SetLights(lights); + + GlfSimpleMaterial material; + + GLfloat color[4], shininess; + glGetMaterialfv(GL_FRONT, GL_AMBIENT, color); + material.SetAmbient(GfVec4f(color)); + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); + material.SetDiffuse(GfVec4f(color)); + glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); + material.SetSpecular(GfVec4f(color)); + glGetMaterialfv(GL_FRONT, GL_EMISSION, color); + material.SetEmission(GfVec4f(color)); + glGetMaterialfv(GL_FRONT, GL_SHININESS, &shininess); + // clamp to 0.0001, since pow(0,0) is undefined in GLSL. + shininess = std::max(0.0001f, shininess); + material.SetShininess(shininess); + + SetMaterial(material); + + GfVec4f sceneAmbient; + glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &sceneAmbient[0]); + SetSceneAmbient(sceneAmbient); +} + +class GlfSimpleLightingContext::_PostSurfaceShaderState +{ +public: + _PostSurfaceShaderState(size_t hash, GlfSimpleLightVector const &lights) + : _hash(hash) + { + _Init(lights); + } + + std::string const &GetShaderSource() const + { + return _shaderSource; + } + + GlfUniformBlockRefPtr const &GetUniformBlock() const + { + return _uniformBlock; + } + + size_t GetHash() const + { + return _hash; + } + +private: + void _Init(GlfSimpleLightVector const &lights); + + std::string _shaderSource; + ; + GlfUniformBlockRefPtr _uniformBlock; + size_t _hash; +}; + +void GlfSimpleLightingContext::_PostSurfaceShaderState::_Init( + GlfSimpleLightVector const &lights) +{ + TRACE_FUNCTION(); + + // Generate shader code and aggregate uniform block data + + // + // layout(std140) uniform PostSurfaceShaderParams { + // MurkPostParams light1; + // CausticsParams light2; + // ... + // } postSurface; + // + // MAT4 GetWorldToViewInverseMatrix(); + // vec4 postSurfaceShader(vec4 Peye, vec3 Neye, vec4 color) + // { + // vec4 Pworld = vec4(GetWorldToViewInverseMatrix() * Peye); + // color = ApplyMurkPostWorldSpace(postSurface.light1,color,Pworld.xyz); + // color = ApplyCausticsWorldSpace(postSurface.light2,color,Pworld.xyz); + // ... + // return color + // } + // + std::stringstream lightsSourceStr; + std::stringstream paramsSourceStr; + std::stringstream applySourceStr; + + std::vector uniformData; + + std::set activeShaderIdentifiers; + size_t activeShaders = 0; + for (GlfSimpleLight const &light : lights) + { + + TfToken const &shaderIdentifier = light.GetPostSurfaceIdentifier(); + std::string const &shaderSource = light.GetPostSurfaceShaderSource(); + VtUCharArray const &shaderParams = light.GetPostSurfaceShaderParams(); + + if (shaderIdentifier.IsEmpty() || + shaderSource.empty() || + shaderParams.empty()) + { + continue; + } + + // omit lights with misaligned parameter data + // GLSL std140 packing has a base alignment of "vec4" + size_t const std140Alignment = 4 * sizeof(float); + if ((shaderParams.size() % std140Alignment) != 0) + { + TF_CODING_ERROR("Invalid shader params size (%zd bytes) " + "for %s (must be a multiple of %zd)\n", + shaderParams.size(), + light.GetID().GetText(), + std140Alignment); + continue; + } + + TF_DEBUG(GLF_DEBUG_POST_SURFACE_LIGHTING).Msg("PostSurfaceLight: %s: %s\n", shaderIdentifier.GetText(), light.GetID().GetText()); + + ++activeShaders; + + // emit per-light type shader source only one time + if (!activeShaderIdentifiers.count(shaderIdentifier)) + { + activeShaderIdentifiers.insert(shaderIdentifier); + lightsSourceStr << shaderSource; + } + + // add a per-light parameter declaration to the uniform block + paramsSourceStr << " " + << shaderIdentifier << "Params " + << "light" << activeShaders << ";\n"; + + // append a call to apply the shader with per-light parameters + applySourceStr << " " + << "color = Apply" << shaderIdentifier << "WorldSpace(" + << "postSurface.light" << activeShaders << ", color, Pworld.xyz" + << ");\n"; + + uniformData.insert(uniformData.end(), + shaderParams.begin(), shaderParams.end()); + } + + if (activeShaders < 1) + { + return; + } + + _shaderSource = lightsSourceStr.str(); + + _shaderSource += + "layout(std140) uniform PostSurfaceShaderParams {\n"; + _shaderSource += paramsSourceStr.str(); + _shaderSource += + "} postSurface;\n\n"; + + _shaderSource += + "MAT4 GetWorldToViewInverseMatrix();\n" + "vec4 postSurfaceShader(vec4 Peye, vec3 Neye, vec4 color)\n" + "{\n" + " vec4 Pworld = vec4(GetWorldToViewInverseMatrix() * Peye);\n" + " color.rgb /= color.a;\n"; + _shaderSource += applySourceStr.str(); + _shaderSource += + " color.rgb *= color.a;\n" + " return color;\n" + "}\n\n"; + + _uniformBlock = GlfUniformBlock::New("_postSurfaceShaderUniformBlock"); + _uniformBlock->Update(uniformData.data(), uniformData.size()); +} + +static size_t +_ComputeHash(GlfSimpleLightVector const &lights) +{ + TRACE_FUNCTION(); + + // hash includes light type and shader source but not parameter values + size_t hash = 0; + for (GlfSimpleLight const &light : lights) + { + TfToken const &identifier = light.GetPostSurfaceIdentifier(); + std::string const &shaderSource = light.GetPostSurfaceShaderSource(); + + hash = ArchHash64(identifier.GetText(), identifier.size(), hash); + hash = ArchHash64(shaderSource.c_str(), shaderSource.size(), hash); + } + + return hash; +} + +void GlfSimpleLightingContext::_ComputePostSurfaceShaderState() +{ + size_t hash = _ComputeHash(GetLights()); + if (!_postSurfaceShaderState || + (_postSurfaceShaderState->GetHash() != hash)) + { + _postSurfaceShaderState.reset( + new _PostSurfaceShaderState(hash, GetLights())); + } + _postSurfaceShaderStateValid = true; +} + +size_t +GlfSimpleLightingContext::ComputeShaderSourceHash() +{ + if (!_postSurfaceShaderStateValid) + { + _ComputePostSurfaceShaderState(); + } + + if (_postSurfaceShaderState) + { + return _postSurfaceShaderState->GetHash(); + } + + return 0; +} + +std::string const & +GlfSimpleLightingContext::ComputeShaderSource(TfToken const &shaderStageKey) +{ + if (!_postSurfaceShaderStateValid) + { + _ComputePostSurfaceShaderState(); + } + + if (_postSurfaceShaderState && + shaderStageKey == HioGlslfxTokens->fragmentShader) + { + return _postSurfaceShaderState->GetShaderSource(); + } + + static const std::string empty; + return empty; +} + +void GlfSimpleLightingContext::_BindPostSurfaceShaderParams( + GlfBindingMapPtr const &bindingMap) +{ + if (!_postSurfaceShaderStateValid) + { + _ComputePostSurfaceShaderState(); + } + + if (_postSurfaceShaderState && _postSurfaceShaderState->GetUniformBlock()) + { + _postSurfaceShaderState->GetUniformBlock()->Bind(bindingMap, _tokens->postSurfaceShaderUB); + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/simpleMaterial.cpp b/Sources/Glf/simpleMaterial.cpp similarity index 55% rename from Sources/OpenUSD/imaging/glf/simpleMaterial.cpp rename to Sources/Glf/simpleMaterial.cpp index 16fbe36e58..c9b6f7c7e4 100644 --- a/Sources/OpenUSD/imaging/glf/simpleMaterial.cpp +++ b/Sources/Glf/simpleMaterial.cpp @@ -23,19 +23,17 @@ // /// \file simpleMaterial.cpp -#include "pxr/imaging/glf/simpleMaterial.h" +#include "Glf/simpleMaterial.h" -#include "pxr/imaging/garch/glApi.h" +#include "Garch/glApi.h" PXR_NAMESPACE_OPEN_SCOPE - -GlfSimpleMaterial::GlfSimpleMaterial() : - _ambient(0.2, 0.2, 0.2, 1), - _diffuse(0.8, 0.8, 0.8, 1), - _specular(0.5, 0.5, 0.5, 1), - _emission(0, 0, 0, 1), - _shininess(32.0) +GlfSimpleMaterial::GlfSimpleMaterial() : _ambient(0.2, 0.2, 0.2, 1), + _diffuse(0.8, 0.8, 0.8, 1), + _specular(0.5, 0.5, 0.5, 1), + _emission(0, 0, 0, 1), + _shininess(32.0) { } @@ -46,80 +44,66 @@ GlfSimpleMaterial::~GlfSimpleMaterial() GfVec4f const & GlfSimpleMaterial::GetAmbient() const { - return _ambient; + return _ambient; } -void -GlfSimpleMaterial::SetAmbient(GfVec4f const & ambient) +void GlfSimpleMaterial::SetAmbient(GfVec4f const &ambient) { - _ambient = ambient; + _ambient = ambient; } - GfVec4f const & GlfSimpleMaterial::GetDiffuse() const { - return _diffuse; + return _diffuse; } -void -GlfSimpleMaterial::SetDiffuse(GfVec4f const & diffuse) +void GlfSimpleMaterial::SetDiffuse(GfVec4f const &diffuse) { - _diffuse = diffuse; + _diffuse = diffuse; } - GfVec4f const & GlfSimpleMaterial::GetSpecular() const { - return _specular; + return _specular; } -void -GlfSimpleMaterial::SetSpecular(GfVec4f const & specular) +void GlfSimpleMaterial::SetSpecular(GfVec4f const &specular) { - _specular = specular; + _specular = specular; } GfVec4f const & GlfSimpleMaterial::GetEmission() const { - return _emission; + return _emission; } -void -GlfSimpleMaterial::SetEmission(GfVec4f const & emission) +void GlfSimpleMaterial::SetEmission(GfVec4f const &emission) { - _emission = emission; + _emission = emission; } double GlfSimpleMaterial::GetShininess() const { - return _shininess; + return _shininess; } -void -GlfSimpleMaterial::SetShininess(double shininess) +void GlfSimpleMaterial::SetShininess(double shininess) { - _shininess = shininess; + _shininess = shininess; } -bool -GlfSimpleMaterial::operator ==(GlfSimpleMaterial const & other) const +bool GlfSimpleMaterial::operator==(GlfSimpleMaterial const &other) const { - return (_ambient == other._ambient - && _diffuse == other._diffuse - && _specular == other._specular - && _emission == other._emission - && _shininess == other._shininess); + return (_ambient == other._ambient && _diffuse == other._diffuse && _specular == other._specular && _emission == other._emission && _shininess == other._shininess); } -bool -GlfSimpleMaterial::operator !=(GlfSimpleMaterial const & other) const +bool GlfSimpleMaterial::operator!=(GlfSimpleMaterial const &other) const { - return !(*this == other); + return !(*this == other); } PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/Glf/simpleShadowArray.cpp b/Sources/Glf/simpleShadowArray.cpp new file mode 100644 index 0000000000..12135be8a9 --- /dev/null +++ b/Sources/Glf/simpleShadowArray.cpp @@ -0,0 +1,468 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +/// \file simpleShadowArray.cpp + +#include "Garch/glApi.h" + +#include "Glf/simpleShadowArray.h" +#include "Glf/debugCodes.h" +#include "Glf/diagnostic.h" +#include "Glf/glContext.h" +#include "Hio/image.h" + +#include "Arch/fileSystem.h" +#include "Gf/vec2i.h" +#include "Gf/vec4d.h" +#include "Tf/debug.h" +#include "Tf/envSetting.h" +#include "Tf/stringUtils.h" + +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +GlfSimpleShadowArray::GlfSimpleShadowArray() : _framebuffer(0), + _shadowDepthSampler(0), + _shadowCompareSampler(0), + _unbindRestoreDrawFramebuffer(0), + _unbindRestoreReadFramebuffer(0), + _unbindRestoreViewport{0, 0, 0, 0}, + _texturesAllocatedExternally(false) +{ +} + +GlfSimpleShadowArray::~GlfSimpleShadowArray() +{ + _FreeResources(); +} + +GLuint +GlfSimpleShadowArray::GetShadowMapTexture(int shadowIndex) const +{ + return _textures[shadowIndex]; +} +GLuint +GlfSimpleShadowArray::GetShadowMapDepthSampler() const +{ + if (!_shadowDepthSampler) + { + TF_CODING_ERROR("Shadow depth sampler has not been allocated"); + } + return _shadowDepthSampler; +} + +GLuint +GlfSimpleShadowArray::GetShadowMapCompareSampler() const +{ + if (!_shadowCompareSampler) + { + TF_CODING_ERROR("Shadow compare sampler has not been allocated"); + } + return _shadowCompareSampler; +} + +void GlfSimpleShadowArray::SetShadowMapResolutions( + std::vector const &resolutions) +{ + if (_resolutions == resolutions) + { + return; + } + + _resolutions = resolutions; + + if (!_texturesAllocatedExternally) + { + _FreeTextures(); + } + + size_t numShadowMaps = _resolutions.size(); + if (_viewMatrix.size() != numShadowMaps || + _projectionMatrix.size() != numShadowMaps) + { + _viewMatrix.resize(numShadowMaps, GfMatrix4d().SetIdentity()); + _projectionMatrix.resize(numShadowMaps, GfMatrix4d().SetIdentity()); + } + + _texturesAllocatedExternally = false; +} + +size_t +GlfSimpleShadowArray::GetNumShadowMapPasses() const +{ + // we require one pass per shadow map. + return _resolutions.size(); +} + +GfVec2i +GlfSimpleShadowArray::GetShadowMapSize(size_t index) const +{ + GfVec2i shadowMapSize(0); + if (TF_VERIFY(index < _resolutions.size())) + { + shadowMapSize = _resolutions[index]; + } + + return shadowMapSize; +} + +GfMatrix4d +GlfSimpleShadowArray::GetViewMatrix(size_t index) const +{ + if (!TF_VERIFY(index < _viewMatrix.size())) + { + return GfMatrix4d(1.0); + } + + return _viewMatrix[index]; +} + +void GlfSimpleShadowArray::SetViewMatrix(size_t index, GfMatrix4d const &matrix) +{ + if (!TF_VERIFY(index < _viewMatrix.size())) + { + return; + } + + _viewMatrix[index] = matrix; +} + +GfMatrix4d +GlfSimpleShadowArray::GetProjectionMatrix(size_t index) const +{ + if (!TF_VERIFY(index < _projectionMatrix.size())) + { + return GfMatrix4d(1.0); + } + + return _projectionMatrix[index]; +} + +void GlfSimpleShadowArray::SetProjectionMatrix(size_t index, GfMatrix4d const &matrix) +{ + if (!TF_VERIFY(index < _projectionMatrix.size())) + { + return; + } + + _projectionMatrix[index] = matrix; +} + +GfMatrix4d +GlfSimpleShadowArray::GetWorldToShadowMatrix(size_t index) const +{ + GfMatrix4d size = GfMatrix4d().SetScale(GfVec3d(0.5, 0.5, 0.5)); + GfMatrix4d center = GfMatrix4d().SetTranslate(GfVec3d(0.5, 0.5, 0.5)); + return GetViewMatrix(index) * GetProjectionMatrix(index) * size * center; +} + +void GlfSimpleShadowArray::BeginCapture(size_t index, bool clear) +{ + _BindFramebuffer(index); + + if (clear) + { + glClear(GL_DEPTH_BUFFER_BIT); + } + + // save the current viewport + glGetIntegerv(GL_VIEWPORT, _unbindRestoreViewport); + + GfVec2i resolution = GetShadowMapSize(index); + glViewport(0, 0, resolution[0], resolution[1]); + + // depth 1.0 means infinity (no occluders). + // This value is also used as a border color + glDepthRange(0, 0.99999); + glEnable(GL_DEPTH_CLAMP); + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfSimpleShadowArray::EndCapture(size_t index) +{ + // reset to GL default, except viewport + glDepthRange(0, 1.0); + glDisable(GL_DEPTH_CLAMP); + + if (TfDebug::IsEnabled(GLF_DEBUG_DUMP_SHADOW_TEXTURES)) + { + HioImage::StorageSpec storage; + GfVec2i resolution = GetShadowMapSize(index); + storage.width = resolution[0]; + storage.height = resolution[1]; + storage.format = HioFormatFloat32; + + // In OpenGL, (0, 0) is the lower left corner. + storage.flipped = true; + + const int numPixels = storage.width * storage.height; + std::vector pixelData(static_cast(numPixels)); + storage.data = static_cast(pixelData.data()); + + glReadPixels(0, + 0, + storage.width, + storage.height, + GL_DEPTH_COMPONENT, + GL_FLOAT, + storage.data); + + GLfloat minValue = std::numeric_limits::max(); + GLfloat maxValue = -std::numeric_limits::max(); + for (int i = 0; i < numPixels; ++i) + { + const GLfloat pixelValue = pixelData[i]; + if (pixelValue < minValue) + { + minValue = pixelValue; + } + if (pixelValue > maxValue) + { + maxValue = pixelValue; + } + } + + // Remap the pixel data so that the furthest depth sample is white and + // the nearest depth sample is black. + for (int i = 0; i < numPixels; ++i) + { + pixelData[i] = (pixelData[i] - minValue) / (maxValue - minValue); + } + + const std::string outputImageFile = ArchNormPath( + TfStringPrintf("%s/GlfSimpleShadowArray.index_%zu.tif", + ArchGetTmpDir(), + index)); + HioImageSharedPtr image = HioImage::OpenForWriting(outputImageFile); + if (image->Write(storage)) + { + TfDebug::Helper().Msg( + "Wrote shadow texture: %s\n", outputImageFile.c_str()); + } + else + { + TfDebug::Helper().Msg( + "Failed to write shadow texture: %s\n", outputImageFile.c_str()); + } + } + + _UnbindFramebuffer(); + + // restore viewport + glViewport(_unbindRestoreViewport[0], + _unbindRestoreViewport[1], + _unbindRestoreViewport[2], + _unbindRestoreViewport[3]); + + GLF_POST_PENDING_GL_ERRORS(); +} + +// --------- private helpers ---------- +bool GlfSimpleShadowArray::_ShadowMapExists() const +{ + return !_textures.empty(); +} + +void GlfSimpleShadowArray::AllocSamplers() +{ + // Samplers + GLfloat border[] = {1, 1, 1, 1}; + + if (!_shadowDepthSampler) + { + glGenSamplers(1, &_shadowDepthSampler); + glSamplerParameteri( + _shadowDepthSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri( + _shadowDepthSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri( + _shadowDepthSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri( + _shadowDepthSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterfv( + _shadowDepthSampler, GL_TEXTURE_BORDER_COLOR, border); + } + + if (!_shadowCompareSampler) + { + glGenSamplers(1, &_shadowCompareSampler); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterfv( + _shadowCompareSampler, GL_TEXTURE_BORDER_COLOR, border); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_COMPARE_MODE, + GL_COMPARE_REF_TO_TEXTURE); + glSamplerParameteri( + _shadowCompareSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } +} + +void GlfSimpleShadowArray::_AllocResources() +{ + // Samplers + AllocSamplers(); + + // Shadow maps + if (!_texturesAllocatedExternally) + { + _AllocTextures(); + } + + // Framebuffer + if (!_framebuffer) + { + glGenFramebuffers(1, &_framebuffer); + } +} + +void GlfSimpleShadowArray::SetTextures(std::vector textureIds) +{ + _textures = textureIds; + _texturesAllocatedExternally = !textureIds.empty(); +} + +void GlfSimpleShadowArray::_AllocTextures() +{ + if (!TF_VERIFY(_shadowDepthSampler) || + !TF_VERIFY(_shadowCompareSampler) || + !TF_VERIFY(_textures.empty())) + { + TF_CODING_ERROR("Unexpected entry state in %s\n", + TF_FUNC_NAME().c_str()); + return; + } + + GlfSharedGLContextScopeHolder sharedContextScopeHolder; + + // XXX: Currently, we allocate/reallocate ALL shadow maps each time. + for (GfVec2i const &size : _resolutions) + { + GLuint id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, + size[0], size[1], 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + _textures.push_back(id); + + TF_DEBUG(GLF_DEBUG_SHADOW_TEXTURES).Msg("Created shadow map texture of size %dx%d " + "(id %#x)\n", + size[0], size[1], id); + } + + glBindTexture(GL_TEXTURE_2D, 0); + _texturesAllocatedExternally = false; +} + +void GlfSimpleShadowArray::_FreeResources() +{ + GlfSharedGLContextScopeHolder sharedContextScopeHolder; + + if (!_texturesAllocatedExternally) + { + _FreeTextures(); + } + + if (_framebuffer) + { + glDeleteFramebuffers(1, &_framebuffer); + _framebuffer = 0; + } + if (_shadowDepthSampler) + { + glDeleteSamplers(1, &_shadowDepthSampler); + _shadowDepthSampler = 0; + } + if (_shadowCompareSampler) + { + glDeleteSamplers(1, &_shadowCompareSampler); + _shadowCompareSampler = 0; + } +} + +void GlfSimpleShadowArray::_FreeTextures() +{ + if (!_textures.empty()) + { + GlfSharedGLContextScopeHolder sharedContextScopeHolder; + // XXX: Ideally, we don't deallocate all textures, and only those that + // have resolution modified. + + for (GLuint const &id : _textures) + { + if (id) + { + glDeleteTextures(1, &id); + } + } + _textures.clear(); + + GLF_POST_PENDING_GL_ERRORS(); + } +} + +void GlfSimpleShadowArray::_BindFramebuffer(size_t index) +{ + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, + (GLint *)&_unbindRestoreDrawFramebuffer); + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, + (GLint *)&_unbindRestoreReadFramebuffer); + + if (!_framebuffer || !_ShadowMapExists()) + { + _AllocResources(); + } + + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + + if (index < _textures.size()) + { + glFramebufferTexture(GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, _textures[index], 0); + } + else + { + TF_CODING_WARNING("Texture index is out of bounds"); + } + + GLF_POST_PENDING_GL_ERRORS(); +} + +void GlfSimpleShadowArray::_UnbindFramebuffer() +{ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _unbindRestoreDrawFramebuffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, _unbindRestoreReadFramebuffer); + + GLF_POST_PENDING_GL_ERRORS(); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/testGLContext.cpp b/Sources/Glf/testGLContext.cpp new file mode 100644 index 0000000000..a9fca432d4 --- /dev/null +++ b/Sources/Glf/testGLContext.cpp @@ -0,0 +1,244 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "Glf/testGLContext.h" + +#include "Tf/diagnostic.h" + +#if (defined(__linux__) || defined(_WIN32)) && __has_include() +# define WITH_TEST_GL_CONTEXT 1 +# include +# else // !defined(__linux__) && !defined(_WIN32) && !__has_include() +# define WITH_TEST_GL_CONTEXT 0 +#endif // defined(__linux__) || defined(_WIN32) && __has_include() + +#include + +#if WITH_TEST_GL_CONTEXT + +PXR_NAMESPACE_OPEN_SCOPE + +class Glf_TestGLContextPrivate +{ +public: + Glf_TestGLContextPrivate(Glf_TestGLContextPrivate const *other = NULL); + + void makeCurrent() const; + + bool isValid(); + + bool operator==(const Glf_TestGLContextPrivate &rhs) const + { + return _dpy == rhs._dpy && _context == rhs._context; + } + + static const Glf_TestGLContextPrivate *currentContext(); + + static bool areSharing(const Glf_TestGLContextPrivate *context1, + const Glf_TestGLContextPrivate *context2); + +private: + Display *_dpy; + + GLXContext _context; + + Glf_TestGLContextPrivate const *_sharedContext; + + static GLXWindow _win; + + static Glf_TestGLContextPrivate const *_currenGLContext; +}; + +Glf_TestGLContextPrivate const *Glf_TestGLContextPrivate::_currenGLContext = NULL; +GLXWindow Glf_TestGLContextPrivate::_win = 0; + +Glf_TestGLContextPrivate::Glf_TestGLContextPrivate(Glf_TestGLContextPrivate const *other) + : _dpy(NULL), _context(NULL) +{ + static int attribs[] = {GLX_DOUBLEBUFFER, GLX_RGBA_BIT, + GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, + GLX_SAMPLE_BUFFERS, 1, GLX_SAMPLES, 4, None}; + + _dpy = XOpenDisplay(0); + + int n; + GLXFBConfig *fbConfigs = glXChooseFBConfig(_dpy, + DefaultScreen(_dpy), attribs, &n); + + GLXContext share = other ? other->_context : 0; + + _context = glXCreateNewContext(_dpy, + fbConfigs[0], GLX_RGBA_TYPE, share, true); + + _sharedContext = other ? other : this; + + if (!_win) + { + XVisualInfo *vi = glXGetVisualFromFBConfig(_dpy, fbConfigs[0]); + + XSetWindowAttributes swa; + swa.colormap = XCreateColormap(_dpy, RootWindow(_dpy, vi->screen), + vi->visual, AllocNone); + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask; + + Window xwin = XCreateWindow(_dpy, RootWindow(_dpy, vi->screen), + 0, 0, 256, 256, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &swa); + + _win = glXCreateWindow(_dpy, fbConfigs[0], xwin, NULL); + } +} + +void Glf_TestGLContextPrivate::makeCurrent() const +{ + glXMakeContextCurrent(_dpy, _win, _win, _context); + + _currenGLContext = this; +} + +bool Glf_TestGLContextPrivate::isValid() +{ + return _context != NULL; +} + +const Glf_TestGLContextPrivate * +Glf_TestGLContextPrivate::currentContext() +{ + return _currenGLContext; +} + +bool Glf_TestGLContextPrivate::areSharing(const Glf_TestGLContextPrivate *context1, const Glf_TestGLContextPrivate *context2) +{ + if (!context1 || !context2) + return false; + + return context1->_sharedContext == context2->_sharedContext; +} + +Glf_TestGLContextPrivate * +_GetSharedContext() +{ + static Glf_TestGLContextPrivate *sharedCtx = new Glf_TestGLContextPrivate(); + return sharedCtx; +} + +// +// GlfTestGLContextRegistrationInterface +// + +class GlfTestGLContextRegistrationInterface : public GlfGLContextRegistrationInterface +{ +public: + GlfTestGLContextRegistrationInterface(); + virtual ~GlfTestGLContextRegistrationInterface(); + + // GlfGLContextRegistrationInterface overrides + virtual GlfGLContextSharedPtr GetShared(); + virtual GlfGLContextSharedPtr GetCurrent(); +}; + +GlfTestGLContextRegistrationInterface::GlfTestGLContextRegistrationInterface() +{ + // Do nothing +} + +GlfTestGLContextRegistrationInterface::~GlfTestGLContextRegistrationInterface() +{ + // Do nothing +} + +GlfGLContextSharedPtr +GlfTestGLContextRegistrationInterface::GetShared() +{ + return GlfGLContextSharedPtr(new GlfTestGLContext(_GetSharedContext())); +} + +GlfGLContextSharedPtr +GlfTestGLContextRegistrationInterface::GetCurrent() +{ + if (const Glf_TestGLContextPrivate *context = + Glf_TestGLContextPrivate::currentContext()) + { + return GlfGLContextSharedPtr(new GlfTestGLContext(context)); + } + return GlfGLContextSharedPtr(); +} + +// +// GlfTestGLContext +// + +GlfTestGLContextSharedPtr +GlfTestGLContext::Create(GlfTestGLContextSharedPtr const &share) +{ + Glf_TestGLContextPrivate *ctx = new Glf_TestGLContextPrivate( + share && share->_context ? share->_context : NULL); + return GlfTestGLContextSharedPtr(new GlfTestGLContext(ctx)); +} + +void GlfTestGLContext::RegisterGLContextCallbacks() +{ + new GlfTestGLContextRegistrationInterface; +} + +GlfTestGLContext::GlfTestGLContext(Glf_TestGLContextPrivate const *context) : _context(const_cast(context)) +{ +} + +bool GlfTestGLContext::IsValid() const +{ + return (_context && _context->isValid()); +} + +void GlfTestGLContext::_MakeCurrent() +{ + _context->makeCurrent(); +} + +bool GlfTestGLContext::_IsSharing(GlfGLContextSharedPtr const &otherContext) const +{ +#ifdef MENV30 + GlfTestGLContextSharedPtr otherGlfTestGLContext = + std::dynamic_pointer_cast(otherContext); + return (otherGlfTestGLContext && + Glf_TestGLContextPrivate::areSharing(_context, otherGlfTestGLContext->_context)); +#else + TF_CODING_ERROR("Glf_TestGLContextPrivate::areSharing() is not supported outside of Presto."); + return false; +#endif +} + +bool GlfTestGLContext::_IsEqual(GlfGLContextSharedPtr const &rhs) const +{ + if (const GlfTestGLContext *rhsRaw = + dynamic_cast(rhs.get())) + { + return *_context == *rhsRaw->_context; + } + return false; +} + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // WITH_TEST_GL_CONTEXT diff --git a/Sources/OpenUSD/imaging/glf/texture.cpp b/Sources/Glf/texture.cpp similarity index 50% rename from Sources/OpenUSD/imaging/glf/texture.cpp rename to Sources/Glf/texture.cpp index 6d8586fc5c..632c9fc319 100644 --- a/Sources/OpenUSD/imaging/glf/texture.cpp +++ b/Sources/Glf/texture.cpp @@ -22,128 +22,114 @@ // language governing permissions and limitations under the Apache License. // /// \file texture.cpp -#include "pxr/imaging/glf/texture.h" -#include "pxr/base/tf/registryManager.h" -#include "pxr/base/tf/type.h" +#include "Glf/texture.h" +#include "Tf/registryManager.h" +#include "Tf/type.h" #include PXR_NAMESPACE_OPEN_SCOPE - TF_REGISTRY_FUNCTION(TfType) { - TfType::Define(); + TfType::Define(); } TF_DEFINE_PUBLIC_TOKENS(GlfTextureTokens, GLF_TEXTURE_TOKENS); -static size_t _TextureMemoryAllocated=0; -static size_t _TextureContentsID=0; +static size_t _TextureMemoryAllocated = 0; +static size_t _TextureContentsID = 0; static size_t _GetNewContentsID() { - return ++_TextureContentsID; + return ++_TextureContentsID; } -GlfTexture::GlfTexture( ) - : _memoryUsed(0) - , _memoryRequested(INT_MAX) - , _contentsID(_GetNewContentsID()) - , _originLocation(HioImage::OriginUpperLeft) +GlfTexture::GlfTexture() + : _memoryUsed(0), _memoryRequested(INT_MAX), _contentsID(_GetNewContentsID()), _originLocation(HioImage::OriginUpperLeft) { } GlfTexture::GlfTexture(HioImage::ImageOriginLocation originLocation) - : _memoryUsed(0) - , _memoryRequested(INT_MAX) - , _contentsID(_GetNewContentsID()) - , _originLocation(originLocation) + : _memoryUsed(0), _memoryRequested(INT_MAX), _contentsID(_GetNewContentsID()), _originLocation(originLocation) { } -GlfTexture::~GlfTexture( ) +GlfTexture::~GlfTexture() { - _TextureMemoryAllocated-=_memoryUsed; + _TextureMemoryAllocated -= _memoryUsed; } size_t -GlfTexture::GetMemoryRequested( ) const +GlfTexture::GetMemoryRequested() const { - return _memoryRequested; + return _memoryRequested; } -void -GlfTexture::SetMemoryRequested(size_t targetMemory) +void GlfTexture::SetMemoryRequested(size_t targetMemory) { - if (_memoryRequested != targetMemory) { - _memoryRequested = targetMemory; - _OnMemoryRequestedDirty(); - } + if (_memoryRequested != targetMemory) + { + _memoryRequested = targetMemory; + _OnMemoryRequestedDirty(); + } } -void -GlfTexture::_OnMemoryRequestedDirty() +void GlfTexture::_OnMemoryRequestedDirty() { - // do nothing in base class + // do nothing in base class } -size_t -GlfTexture::GetMemoryUsed( ) const +size_t +GlfTexture::GetMemoryUsed() const { - return _memoryUsed; + return _memoryUsed; } -void -GlfTexture::_SetMemoryUsed( size_t s ) +void GlfTexture::_SetMemoryUsed(size_t s) { - _TextureMemoryAllocated += s - _memoryUsed; + _TextureMemoryAllocated += s - _memoryUsed; - _memoryUsed = s; + _memoryUsed = s; } -bool -GlfTexture::IsMinFilterSupported(GLenum filter) +bool GlfTexture::IsMinFilterSupported(GLenum filter) { - return true; + return true; } -bool -GlfTexture::IsMagFilterSupported(GLenum filter) +bool GlfTexture::IsMagFilterSupported(GLenum filter) { - return true; + return true; } -size_t +size_t GlfTexture::GetTextureMemoryAllocated() { - return _TextureMemoryAllocated; + return _TextureMemoryAllocated; } size_t GlfTexture::GetContentsID() const { - return _contentsID; + return _contentsID; } -void -GlfTexture::_UpdateContentsID() +void GlfTexture::_UpdateContentsID() { - _contentsID = _GetNewContentsID(); + _contentsID = _GetNewContentsID(); } -HioImage::ImageOriginLocation +HioImage::ImageOriginLocation GlfTexture::GetOriginLocation() const { - return _originLocation; + return _originLocation; } -bool -GlfTexture::IsOriginLowerLeft() const +bool GlfTexture::IsOriginLowerLeft() const { - return _originLocation == HioImage::OriginLowerLeft; + return _originLocation == HioImage::OriginLowerLeft; } PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/Glf/uniformBlock.cpp b/Sources/Glf/uniformBlock.cpp new file mode 100644 index 0000000000..688d901696 --- /dev/null +++ b/Sources/Glf/uniformBlock.cpp @@ -0,0 +1,99 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +// uniformBlock.cpp +// + +#include "Garch/glApi.h" + +#include "Glf/diagnostic.h" +#include "Glf/uniformBlock.h" +#include "Glf/bindingMap.h" +#include "Glf/glContext.h" + +PXR_NAMESPACE_OPEN_SCOPE + +GlfUniformBlock::GlfUniformBlock(char const *label) : _buffer(0), _size(0) +{ + glGenBuffers(1, &_buffer); + if (label) + { + // Using 'glObjectLabel' is only guaranteed to work on GL resources that + // have been created. glGenBuffers only reserves an id. + // Postpone setting up the debug label until buffer binding. + _debugLabel = label; + } +} + +GlfUniformBlock::~GlfUniformBlock() +{ + GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; + + if (glIsBuffer(_buffer) == GL_TRUE) + { + glDeleteBuffers(1, &_buffer); + } +} + +GlfUniformBlockRefPtr +GlfUniformBlock::New(char const *label) +{ + return TfCreateRefPtr(new GlfUniformBlock(label)); +} + +void GlfUniformBlock::Bind(GlfBindingMapPtr const &bindingMap, + std::string const &identifier) +{ + if (!bindingMap) + return; + int binding = bindingMap->GetUniformBinding(identifier); + + glBindBufferBase(GL_UNIFORM_BUFFER, binding, _buffer); + + // Binding the buffer should ensure it is created so we can assign debug lbl + if (!_debugLabel.empty()) + { + GlfDebugLabelBuffer(_buffer, _debugLabel.c_str()); + } +} + +void GlfUniformBlock::Update(const void *data, int size) +{ + GLF_GROUP_FUNCTION(); + + glBindBuffer(GL_UNIFORM_BUFFER, _buffer); + if (_size != size) + { + glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STATIC_DRAW); + _size = size; + } + if (size > 0) + { + // Bug 95969 BufferSubData w/ size == 0 should be a noop but + // raises errors on some NVIDIA drivers. + glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data); + } + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/Glf/utils.cpp b/Sources/Glf/utils.cpp new file mode 100644 index 0000000000..4eeec1af17 --- /dev/null +++ b/Sources/Glf/utils.cpp @@ -0,0 +1,275 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +// utils.cpp +// + +#include "Glf/utils.h" + +#include "Tf/diagnostic.h" +#include "Tf/stringUtils.h" + +PXR_NAMESPACE_OPEN_SCOPE + +int GlfGetNumElements(GLenum format) +{ + switch (format) + { + case GL_DEPTH_COMPONENT: + case GL_COLOR_INDEX: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_RED: + return 1; + case GL_LUMINANCE_ALPHA: + case GL_RG: + return 2; + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + default: + TF_CODING_ERROR("Unsupported format"); + return 1; + } +} + +int GlfGetElementSize(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + return sizeof(GLubyte); + case GL_UNSIGNED_SHORT: + case GL_SHORT: + return sizeof(GLshort); + case GL_FLOAT: + return sizeof(GLfloat); + case GL_DOUBLE: + return sizeof(GLdouble); + case GL_HALF_FLOAT: + return sizeof(GLhalf); + default: + TF_CODING_ERROR("Unsupported type"); + return sizeof(GLfloat); + } +} + +HioFormat +GlfGetHioFormat(GLenum glFormat, GLenum glType, bool isSRGB) +{ + switch (glFormat) + { + case GL_DEPTH_COMPONENT: + case GL_COLOR_INDEX: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_RED: + switch (glType) + { + case GL_UNSIGNED_BYTE: + if (isSRGB) + { + return HioFormatUNorm8srgb; + } + return HioFormatUNorm8; + case GL_BYTE: + return HioFormatSNorm8; + case GL_UNSIGNED_SHORT: + return HioFormatUInt16; + case GL_SHORT: + return HioFormatInt16; + case GL_UNSIGNED_INT: + return HioFormatUInt32; + case GL_INT: + return HioFormatInt32; + case GL_HALF_FLOAT: + return HioFormatFloat16; + case GL_FLOAT: + return HioFormatFloat32; + case GL_DOUBLE: + return HioFormatDouble64; + } + case GL_LUMINANCE_ALPHA: + case GL_RG: + switch (glType) + { + case GL_UNSIGNED_BYTE: + if (isSRGB) + { + return HioFormatUNorm8Vec2srgb; + } + return HioFormatUNorm8Vec2; + case GL_BYTE: + return HioFormatSNorm8Vec2; + case GL_UNSIGNED_SHORT: + return HioFormatUInt16Vec2; + case GL_SHORT: + return HioFormatInt16Vec2; + case GL_UNSIGNED_INT: + return HioFormatUInt32Vec2; + case GL_INT: + return HioFormatInt32Vec2; + case GL_HALF_FLOAT: + return HioFormatFloat16Vec2; + case GL_FLOAT: + return HioFormatFloat32Vec2; + case GL_DOUBLE: + return HioFormatDouble64Vec2; + } + case GL_RGB: + switch (glType) + { + case GL_UNSIGNED_BYTE: + if (isSRGB) + { + return HioFormatUNorm8Vec3srgb; + } + return HioFormatUNorm8Vec3; + case GL_BYTE: + return HioFormatSNorm8Vec3; + case GL_UNSIGNED_SHORT: + return HioFormatUInt16Vec3; + case GL_SHORT: + return HioFormatInt16Vec3; + case GL_UNSIGNED_INT: + return HioFormatUInt32Vec3; + case GL_INT: + return HioFormatInt32Vec3; + case GL_HALF_FLOAT: + return HioFormatFloat16Vec3; + case GL_FLOAT: + return HioFormatFloat32Vec3; + case GL_DOUBLE: + return HioFormatDouble64Vec3; + } + case GL_RGBA: + switch (glType) + { + case GL_UNSIGNED_BYTE: + if (isSRGB) + { + return HioFormatUNorm8Vec4srgb; + } + return HioFormatUNorm8Vec4; + case GL_BYTE: + return HioFormatSNorm8Vec4; + case GL_UNSIGNED_SHORT: + return HioFormatUInt16Vec4; + case GL_SHORT: + return HioFormatInt16Vec4; + case GL_UNSIGNED_INT: + return HioFormatUInt32Vec4; + case GL_INT: + return HioFormatInt32Vec4; + case GL_HALF_FLOAT: + return HioFormatFloat16Vec4; + case GL_FLOAT: + return HioFormatFloat32Vec4; + case GL_DOUBLE: + return HioFormatDouble64Vec4; + } + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + return HioFormatBC6UFloatVec3; + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: + return HioFormatBC6FloatVec3; + case GL_COMPRESSED_RGBA_BPTC_UNORM: + return HioFormatBC7UNorm8Vec4; + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + return HioFormatBC7UNorm8Vec4srgb; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return HioFormatBC1UNorm8Vec4; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return HioFormatBC3UNorm8Vec4; + default: + TF_CODING_ERROR("Unsupported type"); + return HioFormatUNorm8Vec3; + } +} + +bool GlfCheckGLFrameBufferStatus(GLuint target, std::string *reason) +{ + GLenum status = glCheckFramebufferStatus(target); + + switch (status) + { + case GL_FRAMEBUFFER_COMPLETE: + return true; + case GL_FRAMEBUFFER_UNSUPPORTED: + if (reason) + { + *reason = "Framebuffer unsupported"; + } + return false; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + if (reason) + { + *reason = "Framebuffer incomplete attachment"; + } + return false; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + if (reason) + { + *reason = "Framebuffer incomplete missing attachment"; + } + return false; +#if defined(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + if (reason) + { + *reason = "Framebuffer incomplete dimensions"; + } + return false; +#endif +#if defined(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + if (reason) + { + *reason = "Framebuffer incomplete formats"; + } + return false; +#endif + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + if (reason) + { + *reason = "Framebuffer incomplete draw buffer"; + } + return false; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + if (reason) + { + *reason = "Framebuffer incomplete read buffer"; + } + return false; + default: + if (reason) + { + *reason = TfStringPrintf( + "Framebuffer error 0x%x", (unsigned int)(status)); + } + return false; + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/CMakeLists.txt b/Sources/OpenUSD/imaging/glf/CMakeLists.txt deleted file mode 100644 index 7425510d5f..0000000000 --- a/Sources/OpenUSD/imaging/glf/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -set(PXR_PREFIX pxr/imaging) -set(PXR_PACKAGE glf) - -if (NOT ${PXR_ENABLE_GL_SUPPORT}) - message(STATUS - "Skipping ${PXR_PACKAGE} because PXR_ENABLE_GL_SUPPORT is OFF") - return() -endif() - -set(optionalPublicClasses "") -if (X11_FOUND) - list(APPEND optionalPublicClasses testGLContext) -endif() - -set(optionalLibs "") -set(optionalIncludeDirs "") - -pxr_library(glf - LIBRARIES - ar - arch - garch - gf - hf - hio - plug - tf - trace - sdf - ${Boost_PYTHON_LIBRARY} - ${OPENGL_gl_LIBRARY} - ${X11_LIBRARIES} - ${optionalLibs} - - INCLUDE_DIRS - ${Boost_INCLUDE_DIRS} - ${optionalIncludeDirs} - - PUBLIC_CLASSES - bindingMap - contextCaps - diagnostic - drawTarget - glContext - glRawContext - info - simpleLight - simpleLightingContext - simpleMaterial - simpleShadowArray - texture - uniformBlock - utils - ${optionalPublicClasses} - - PRIVATE_CLASSES - debugCodes - glContextRegistry - - PUBLIC_HEADERS - api.h - - CPPFILES - ${optionalCppFiles} - - PYTHON_CPPFILES - moduleDeps.cpp - - PYMODULE_CPPFILES - module.cpp - wrapDiagnostic.cpp - wrapDrawTarget.cpp - wrapSimpleLight.cpp - wrapSimpleMaterial.cpp - wrapTexture.cpp - - PYMODULE_FILES - __init__.py - - RESOURCE_FILES - plugInfo.json - shaders/pcfShader.glslfx - shaders/simpleLighting.glslfx - - DOXYGEN_FILES - overview.dox -) diff --git a/Sources/OpenUSD/imaging/glf/bindingMap.cpp b/Sources/OpenUSD/imaging/glf/bindingMap.cpp deleted file mode 100644 index 14416dbf76..0000000000 --- a/Sources/OpenUSD/imaging/glf/bindingMap.cpp +++ /dev/null @@ -1,275 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -/// \file bindingMap.cpp - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/bindingMap.h" -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/stl.h" -#include "pxr/base/tf/type.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -int -GlfBindingMap::GetSamplerUnit(std::string const & name) -{ - return GetSamplerUnit(TfToken(name)); -} - -int -GlfBindingMap::GetSamplerUnit(TfToken const & name) -{ - int samplerUnit = -1; - if (!TfMapLookup(_samplerBindings, name, &samplerUnit)) { - // XXX error check < MAX_TEXTURE_IMAGE_UNITS - samplerUnit = _samplerBindingBaseIndex + (int)_samplerBindings.size(); - _samplerBindings[name] = samplerUnit; - } - TF_VERIFY(samplerUnit >= 0); - return samplerUnit; -} - -int -GlfBindingMap::GetAttributeIndex(std::string const & name) -{ - return GetAttributeIndex(TfToken(name)); -} - -int -GlfBindingMap::GetAttributeIndex(TfToken const & name) -{ - int attribIndex = -1; - if (!TfMapLookup(_attribBindings, name, &attribIndex)) { - return -1; - } - return attribIndex; -} - -void -GlfBindingMap::AssignSamplerUnitsToProgram(GLuint program) -{ - for (BindingMap::value_type const& p : _samplerBindings) { - GLint loc = glGetUniformLocation(program, p.first.GetText()); - if (loc != -1) { - glProgramUniform1i(program, loc, p.second); - } - } -} - -int -GlfBindingMap::GetUniformBinding(std::string const & name) -{ - return GetUniformBinding(TfToken(name)); -} - -int -GlfBindingMap::GetUniformBinding(TfToken const & name) -{ - int binding = -1; - if (!TfMapLookup(_uniformBindings, name, &binding)) { - binding = _uniformBindingBaseIndex + (int)_uniformBindings.size(); - _uniformBindings[name] = binding; - } - TF_VERIFY(binding >= 0); - return binding; -} - -bool -GlfBindingMap::HasUniformBinding(std::string const & name) const -{ - return HasUniformBinding(TfToken(name)); -} - -bool -GlfBindingMap::HasUniformBinding(TfToken const & name) const -{ - return (_uniformBindings.find(name) != _uniformBindings.end()); -} - -void -GlfBindingMap::AssignUniformBindingsToProgram(GLuint program) -{ - for (BindingMap::value_type const& p : _uniformBindings) { - GLuint uboIndex = glGetUniformBlockIndex(program, p.first.GetText()); - if (uboIndex != GL_INVALID_INDEX) { - glUniformBlockBinding(program, uboIndex, p.second); - } - } -} - -void -GlfBindingMap::AddCustomBindings(GLuint program) -{ - _AddActiveAttributeBindings(program); - _AddActiveUniformBindings(program); - _AddActiveUniformBlockBindings(program); - - // assign uniform bindings / texture samplers - AssignUniformBindingsToProgram(program); - AssignSamplerUnitsToProgram(program); -} - -void -GlfBindingMap::_AddActiveAttributeBindings(GLuint program) -{ - GLint numAttributes = 0; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes); - if (numAttributes == 0) return; - - GLint maxNameLength = 0; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); - maxNameLength = std::max(maxNameLength, 100); - GLint size; - GLenum type; - char * name = new char[maxNameLength]; - - for (int i = 0; i < numAttributes; ++i) { - glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name); - GLint location = glGetAttribLocation(program, name); - TfToken token(name); - - BindingMap::iterator it = _attribBindings.find(token); - if (it == _attribBindings.end()) { - _attribBindings[token] = location; - } else if (it->second != location) { - TF_RUNTIME_ERROR("Inconsistent attribute binding detected."); - } - } - - delete[] name; -} - -void -GlfBindingMap::_AddActiveUniformBindings(GLuint program) -{ - GLint numUniforms = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); - if (numUniforms == 0) return; - - GLint maxNameLength = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); - GLint size; - GLenum type; - char * name = new char[maxNameLength]; - - for (int i = 0; i < numUniforms; ++i) { - glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name); - switch(type) { - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - GetSamplerUnit(name); - break; - } - } - delete[] name; -} - -void -GlfBindingMap::_AddActiveUniformBlockBindings(GLuint program) -{ - GLint numUniformBlocks = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); - if (numUniformBlocks == 0) return; - - GLint maxNameLength = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxNameLength); - char *name = new char[maxNameLength]; - - for (int i = 0; i < numUniformBlocks; ++i) { - glGetActiveUniformBlockName(program, i, maxNameLength, NULL, name); - GetUniformBinding(name); - } - delete[] name; -} - -void -GlfBindingMap::Debug() const -{ - printf("GlfBindingMap\n"); - - // sort for comparing baseline in testGlfBindingMap - std::map attribBindings, samplerBindings, uniformBindings; - for (BindingMap::value_type const& p : _attribBindings ) { - attribBindings.insert(p); - } - for (BindingMap::value_type const& p : _samplerBindings ) { - samplerBindings.insert(p); - } - for (BindingMap::value_type const& p : _uniformBindings ) { - uniformBindings.insert(p); - } - - printf(" Attribute bindings\n"); - for (BindingMap::value_type const& p : attribBindings ) { - printf(" %s : %d\n", p.first.GetText(), p.second); - } - printf(" Sampler bindings\n"); - for (BindingMap::value_type const& p : samplerBindings) { - printf(" %s : %d\n", p.first.GetText(), p.second); - } - printf(" Uniform bindings\n"); - for (BindingMap::value_type const& p : uniformBindings) { - printf(" %s : %d\n", p.first.GetText(), p.second); - } -} - - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/contextCaps.cpp b/Sources/OpenUSD/imaging/glf/contextCaps.cpp deleted file mode 100644 index c4367c2925..0000000000 --- a/Sources/OpenUSD/imaging/glf/contextCaps.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright 2018 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/contextCaps.h" - -#include "pxr/imaging/glf/glContext.h" -#include "pxr/imaging/glf/debugCodes.h" - -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/envSetting.h" -#include "pxr/base/tf/instantiateSingleton.h" - -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_INSTANTIATE_SINGLETON(GlfContextCaps); - -// Set defaults based on GL spec minimums -static const int _DefaultMaxArrayTextureLayers = 256; - -// Initialize members to ensure a sane starting state. -GlfContextCaps::GlfContextCaps() - : glVersion(0) - , coreProfile(false) - , maxArrayTextureLayers(_DefaultMaxArrayTextureLayers) -{ -} - -/*static*/ -void -GlfContextCaps::InitInstance() -{ - // Initialize the render context caps. - // This needs to be called on a thread that has the gl context - // bound before we go wide on the cpus. - - // XXX: This should be called on - // an render context change event api. (bug #124971) - - GlfContextCaps& caps = TfSingleton::GetInstance(); - - GarchGLApiLoad(); - - caps._LoadCaps(); -} - -/*static*/ -const GlfContextCaps& -GlfContextCaps::GetInstance() -{ - GlfContextCaps& caps = TfSingleton::GetInstance(); - - if (caps.glVersion == 0) { - TF_CODING_ERROR("GlfContextCaps has not been initialized"); - // Return the default set - } - - return caps; -} - -void -GlfContextCaps::_LoadCaps() -{ - // Reset Values to reasonable defaults based of OpenGL minimums. - // So that if we early out, systems can still depend on the - // caps values being valid. - // - // _LoadCaps can also be called multiple times, so not want - // to mix and match values in the event of an early out. - glVersion = 0; - coreProfile = false; - maxArrayTextureLayers = _DefaultMaxArrayTextureLayers; - - if (!TF_VERIFY(GlfGLContext::GetCurrentGLContext()->IsValid())) { - return; - } - - const char *glVendorStr = (const char*)glGetString(GL_VENDOR); - const char *glRendererStr = (const char*)glGetString(GL_RENDERER); - const char *glVersionStr = (const char*)glGetString(GL_VERSION); - - // GL hasn't been initialized yet. - if (glVersionStr == NULL) return; - - const char *dot = strchr(glVersionStr, '.'); - if (TF_VERIFY((dot && dot != glVersionStr), - "Can't parse GL_VERSION %s", glVersionStr)) { - // GL_VERSION = "4.5.0 " - // "4.1 " - // "4.1 " - int major = std::max(0, std::min(9, *(dot-1) - '0')); - int minor = std::max(0, std::min(9, *(dot+1) - '0')); - glVersion = major * 100 + minor * 10; - } - - if (glVersion >= 320) { - GLint profileMask = 0; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask); - coreProfile = (profileMask & GL_CONTEXT_CORE_PROFILE_BIT); - } - - if (glVersion >= 300) { - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers); - } - - if (TfDebug::IsEnabled(GLF_DEBUG_CONTEXT_CAPS)) { - std::cout - << "GlfContextCaps: \n" - << " GL_VENDOR = " - << glVendorStr << "\n" - << " GL_RENDERER = " - << glRendererStr << "\n" - << " GL_VERSION = " - << glVersionStr << "\n" - << " GL version = " - << glVersion << "\n" - ; - } -} - - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/diagnostic.cpp b/Sources/OpenUSD/imaging/glf/diagnostic.cpp deleted file mode 100644 index 20514bd941..0000000000 --- a/Sources/OpenUSD/imaging/glf/diagnostic.cpp +++ /dev/null @@ -1,335 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -// Diagnostic.cpp -// - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/diagnostic.h" -#include "pxr/imaging/glf/debugCodes.h" -#include "pxr/imaging/glf/glContext.h" - -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/envSetting.h" -#include "pxr/base/tf/stackTrace.h" -#include "pxr/base/tf/stringUtils.h" - -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_DEFINE_ENV_SETTING(GLF_ENABLE_DIAGNOSTIC_TRACE, 0, - "Enable glDebug* diagnostic tracing in Glf."); - -static bool -GlfTraceEnabled() -{ -#if defined(GL_KHR_debug) - static bool _v = TfGetEnvSetting(GLF_ENABLE_DIAGNOSTIC_TRACE) == 1; - return _v; -#else - return false; -#endif -} - -void -GlfPostPendingGLErrors(std::string const & where) -{ - bool foundError = false; - GLenum error; - // Protect from doing infinite looping when glGetError - // is called from an invalid context. - int watchDogCount = 0; - while ((watchDogCount++ < 256) && - ((error = glGetError()) != GL_NO_ERROR)) { - foundError = true; - const GLubyte *errorString = gluErrorString(error); - - std::ostringstream errorMessage; - if (!errorString) { - errorMessage << "GL error code: 0x" << std::hex << error - << std::dec; - } else { - errorMessage << "GL error: " << errorString; - } - - if (!where.empty()) { - errorMessage << ", reported from " << where; - } - - TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg(errorMessage.str() + "\n"); - - TF_RUNTIME_ERROR(errorMessage.str()); - } - if (foundError) { - TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg( - TfStringPrintf("==== GL Error Stack ====\n%s\n", - TfGetStackTrace().c_str())); - } -} - -void -GlfRegisterDefaultDebugOutputMessageCallback() -{ -#if defined(GL_KHR_debug) - if (glDebugMessageCallbackARB) { - glDebugMessageCallbackARB( - (GLDEBUGPROCARB)GlfDefaultDebugOutputMessageCallback, 0); - // Disable push/pop group messages; we don't want to print these. - glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PUSH_GROUP, - GL_DONT_CARE, 0, nullptr, GL_FALSE); - glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP, - GL_DONT_CARE, 0, nullptr, GL_FALSE); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - } -#endif -} - -void -GlfDefaultDebugOutputMessageCallback( - GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, GLchar const * message, GLvoid const * userParam) -{ -#if defined(GL_ARB_debug_output) || defined(GL_VERSION_4_3) - if (type == GL_DEBUG_TYPE_ERROR_ARB) { - TF_RUNTIME_ERROR("GL debug output: " - "source: %s type: %s id: %d severity: %s message: %s", - GlfDebugEnumToString(source), - GlfDebugEnumToString(type), - id, - GlfDebugEnumToString(severity), - message); - - TF_DEBUG(GLF_DEBUG_ERROR_STACKTRACE).Msg( - TfStringPrintf("==== GL Error Stack ====\n%s\n", - TfGetStackTrace().c_str())); - } else { - TF_WARN("GL debug output: %s", message); - } -#endif -} - -char const * -GlfDebugEnumToString(GLenum debugEnum) -{ -#if defined(GL_ARB_debug_output) || defined(GL_VERSION_4_3) - switch (debugEnum) { - case GL_DEBUG_SOURCE_API_ARB: - return "GL_DEBUG_SOURCE_API"; - case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: - return "GL_DEBUG_SOURCE_WINDOW_SYSTEM"; - case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: - return "GL_DEBUG_SOURCE_SHADER_COMPILER"; - case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: - return "GL_DEBUG_SOURCE_THIRD_PARTY"; - case GL_DEBUG_SOURCE_APPLICATION_ARB: - return "GL_DEBUG_SOURCE_APPLICATION"; - case GL_DEBUG_SOURCE_OTHER_ARB: - return "GL_DEBUG_SOURCE_OTHER"; - - case GL_DEBUG_TYPE_ERROR_ARB: - return "GL_DEBUG_TYPE_ERROR"; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: - return "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: - return "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"; - case GL_DEBUG_TYPE_PORTABILITY_ARB: - return "GL_DEBUG_TYPE_PORTABILITY"; - case GL_DEBUG_TYPE_PERFORMANCE_ARB: - return "GL_DEBUG_TYPE_PERFORMANCE"; - case GL_DEBUG_TYPE_OTHER_ARB: - return "GL_DEBUG_TYPE_OTHER"; -#if defined(GL_VERSION_4_3) - case GL_DEBUG_TYPE_MARKER: - return "GL_DEBUG_TYPE_MARKER"; - case GL_DEBUG_TYPE_PUSH_GROUP: - return "GL_DEBUG_TYPE_PUSH_GROUP"; - case GL_DEBUG_TYPE_POP_GROUP: - return "GL_DEBUG_TYPE_POP_GROUP"; -#endif - -#if defined(GL_VERSION_4_3) - case GL_DEBUG_SEVERITY_NOTIFICATION: - return "GL_DEBUG_SEVERITY_NOTIFICATION"; -#endif - case GL_DEBUG_SEVERITY_HIGH_ARB: - return "GL_DEBUG_SEVERITY_HIGH"; - case GL_DEBUG_SEVERITY_MEDIUM_ARB: - return "GL_DEBUG_SEVERITY_MEDIUM"; - case GL_DEBUG_SEVERITY_LOW_ARB: - return "GL_DEBUG_SEVERITY_LOW"; - } -#endif - TF_CODING_ERROR("unknown debug enum"); - return "unknown"; -} - -static void -_GlfPushDebugGroup(char const * message) -{ -#if defined(GL_KHR_debug) - if (GARCH_GLAPI_HAS(KHR_debug)) { - glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 0, -1, message); - } -#endif -} - -static void -_GlfPopDebugGroup() -{ -#if defined(GL_KHR_debug) - if (GARCH_GLAPI_HAS(KHR_debug)) { - glPopDebugGroup(); - } -#endif -} - -GlfDebugGroup::GlfDebugGroup(char const *message) -{ - if (GlfTraceEnabled()) { - _GlfPushDebugGroup(message); - } -} - -GlfDebugGroup::~GlfDebugGroup() -{ - if (GlfTraceEnabled()) { - _GlfPopDebugGroup(); - } -} - -void -GlfDebugLabelBuffer(GLuint id, char const *label) -{ -#if defined(GL_KHR_debug) - if (GlfTraceEnabled()) { - if (GARCH_GLAPI_HAS(KHR_debug)) { - glObjectLabel(GL_BUFFER, id, -1, label); - } - } -#endif -} - -void -GlfDebugLabelShader(GLuint id, char const *label) -{ -#if defined(GL_KHR_debug) - if (GlfTraceEnabled()) { - if (GARCH_GLAPI_HAS(KHR_debug)) { - glObjectLabel(GL_SHADER, id, -1, label); - } - } -#endif -} - -void -GlfDebugLabelProgram(GLuint id, char const *label) -{ -#if defined(GL_KHR_debug) - if (GlfTraceEnabled()) { - if (GARCH_GLAPI_HAS(KHR_debug)) { - glObjectLabel(GL_PROGRAM, id, -1, label); - } - } -#endif -} - -GlfGLQueryObject::GlfGLQueryObject() - : _id(0), _target(0) -{ - GarchGLApiLoad(); - if (glGenQueries) { - glGenQueries(1, &_id); - } -} - -GlfGLQueryObject::~GlfGLQueryObject() -{ - GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; - if (glDeleteQueries && _id) { - glDeleteQueries(1, &_id); - } -} - -void -GlfGLQueryObject::BeginSamplesPassed() -{ - Begin(GL_SAMPLES_PASSED); -} - -void -GlfGLQueryObject::BeginPrimitivesGenerated() -{ - Begin(GL_PRIMITIVES_GENERATED); -} -void -GlfGLQueryObject::BeginTimeElapsed() -{ - Begin(GL_TIME_ELAPSED); -} - -void -GlfGLQueryObject::Begin(GLenum target) -{ - _target = target; - if (glBeginQuery && _id) { - glBeginQuery(_target, _id); - } -} - -void -GlfGLQueryObject::End() -{ - if (glEndQuery && _target) { - glEndQuery(_target); - } - _target = 0; -} - -GLint64 -GlfGLQueryObject::GetResult() -{ - GLint64 value = 0; - if (glGetQueryObjecti64v && _id) { - glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &value); - } - return value; -} - -GLint64 -GlfGLQueryObject::GetResultNoWait() -{ - GLint64 value = 0; - if (glGetQueryObjecti64v && _id) { - glGetQueryObjecti64v(_id, GL_QUERY_RESULT_AVAILABLE, &value); - if (value == GL_TRUE) { - glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &value); - } - } - return value; -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/drawTarget.cpp b/Sources/OpenUSD/imaging/glf/drawTarget.cpp deleted file mode 100644 index b1f8b2b22d..0000000000 --- a/Sources/OpenUSD/imaging/glf/drawTarget.cpp +++ /dev/null @@ -1,832 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -// glf/drawTarget.cpp -// - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/drawTarget.h" -#include "pxr/imaging/glf/glContext.h" -#include "pxr/imaging/glf/diagnostic.h" -#include "pxr/imaging/hio/image.h" -#include "pxr/imaging/glf/utils.h" - -#include "pxr/imaging/hf/perfLog.h" - -#include "pxr/base/tf/stringUtils.h" -#include "pxr/base/tf/envSetting.h" - -#include "pxr/base/trace/trace.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_DEFINE_ENV_SETTING(GLF_DRAW_TARGETS_NUM_SAMPLES, 4, - "Number of samples greater than 1 forces MSAA."); - -static unsigned int -GetNumSamples() -{ - static int reqNumSamples = TfGetEnvSetting(GLF_DRAW_TARGETS_NUM_SAMPLES); - unsigned int numSamples = 1; - if (reqNumSamples > 1) { - numSamples = (reqNumSamples & (reqNumSamples - 1)) ? 1 : reqNumSamples; - } - return numSamples; -} - -GlfDrawTargetRefPtr -GlfDrawTarget::New( GfVec2i const & size, bool requestMSAA ) -{ - return TfCreateRefPtr(new This(size, requestMSAA)); -} - -GlfDrawTarget::GlfDrawTarget( GfVec2i const & size, bool requestMSAA /* =false */) : - _framebuffer(0), - _framebufferMS(0), - _unbindRestoreReadFB(0), - _unbindRestoreDrawFB(0), - _bindDepth(0), - _size(size), - _numSamples(1) -{ - GarchGLApiLoad(); - - // If MSAA has been requested and it is enabled then we will create - // msaa buffers - if (requestMSAA) { - _numSamples = GetNumSamples(); - } - - _GenFrameBuffer(); - - _attachmentsPtr = TfCreateRefPtr( new AttachmentsContainer ); -} - -GlfDrawTargetRefPtr -GlfDrawTarget::New( GlfDrawTargetPtr const & drawtarget ) -{ - return TfCreateRefPtr(new This(drawtarget)); -} - -// clone constructor : generates a new GL framebuffer, but share the texture -// attachments. -GlfDrawTarget::GlfDrawTarget( GlfDrawTargetPtr const & drawtarget ) : - _framebuffer(0), - _framebufferMS(0), - _unbindRestoreReadFB(0), - _unbindRestoreDrawFB(0), - _bindDepth(0), - _size(drawtarget->_size), - _numSamples(drawtarget->_numSamples), - _owningContext() -{ - GarchGLApiLoad(); - - _GenFrameBuffer(); - - // share the RefPtr to the map of attachments - _attachmentsPtr = drawtarget->_attachmentsPtr; - - Bind(); - - // attach the textures to the correct framebuffer mount points - for (AttachmentsMap::value_type const& p : _attachmentsPtr->attachments) { - _BindAttachment( p.second ); - } - - Unbind(); -} - -GlfDrawTarget::~GlfDrawTarget( ) -{ - // If the owning context has died, there's nothing to free. - if (!_owningContext->IsValid()) { - return; - } - - // bind the owning context to make sure we delete frame buffer on correct - // context. - GlfGLContextScopeHolder contextHolder(_owningContext); - - _DeleteAttachments( ); - - if (_framebuffer) { - TF_VERIFY(glIsFramebuffer(_framebuffer), - "Tried to free invalid framebuffer"); - - glDeleteFramebuffers(1, &_framebuffer); - _framebuffer = 0; - } - - if (_framebufferMS) { - TF_VERIFY(glIsFramebuffer(_framebufferMS), - "Tried to free invalid multisampled framebuffer"); - - glDeleteFramebuffers(1, &_framebufferMS); - _framebufferMS = 0; - } -} - -void -GlfDrawTarget::AddAttachment( std::string const & name, - GLenum format, GLenum type, - GLenum internalFormat ) -{ - if (!IsBound()) { - TF_CODING_ERROR("Cannot change the size of an unbound GlfDrawTarget"); - } - - AttachmentsMap & attachments = _GetAttachments(); - AttachmentsMap::iterator it = attachments.find( name ); - - if (it==attachments.end()) { - - AttachmentRefPtr attachment = Attachment::New((int)attachments.size(), - format, type, - internalFormat, _size, - _numSamples); - - attachments.insert(AttachmentsMap::value_type(name, attachment)); - - - TF_VERIFY( attachment->GetGlTextureName() > 0 , - "Attachment \"%s\" was not added " - "and cannot be bound in MatDisplayMaterial", name.c_str()); - - _BindAttachment( attachment ); - - } else { - TF_CODING_ERROR( "Attachment \""+name+"\" already exists for this " - "DrawTarget" ); - } -} - -void -GlfDrawTarget::DeleteAttachment( std::string const & name ) -{ - AttachmentsMap & attachments = _GetAttachments(); - AttachmentsMap::iterator it = attachments.find( name ); - - if (it!=attachments.end()) { - attachments.erase( it ); - } else { - TF_CODING_ERROR( "Attachment \""+name+"\" does not exist for this " - "DrawTarget" ); - } -} - -GlfDrawTarget::AttachmentRefPtr -GlfDrawTarget::GetAttachment(std::string const & name) -{ - AttachmentsMap & attachments = _GetAttachments(); - AttachmentsMap::iterator it = attachments.find( name ); - - if (it!=attachments.end()) { - return it->second; - } else { - return TfNullPtr; - } -} - -void -GlfDrawTarget::ClearAttachments() -{ - _DeleteAttachments(); -} - -void -GlfDrawTarget::CloneAttachments( GlfDrawTargetPtr const & drawtarget ) -{ - if (!drawtarget) { - TF_CODING_ERROR( "Cannot clone TfNullPtr attachments." ); - } - - // garbage collection will take care of the existing instance pointed to - // by the RefPtr - _attachmentsPtr = drawtarget->_attachmentsPtr; - - for (AttachmentsMap::value_type const& p : _attachmentsPtr->attachments) { - _BindAttachment( p.second ); - } -} - -GlfDrawTarget::AttachmentsMap const & -GlfDrawTarget::GetAttachments() const -{ - return _GetAttachments(); -} - -GlfDrawTarget::AttachmentsMap & -GlfDrawTarget::_GetAttachments() const -{ - TF_VERIFY( _attachmentsPtr, - "DrawTarget has uninitialized attachments map."); - - return _attachmentsPtr->attachments; -} - -void -GlfDrawTarget::SetSize( GfVec2i size ) -{ - if (size==_size) { - return; - } - - if (!IsBound()) { - TF_CODING_ERROR( "Cannot change the size of an unbound DrawTarget" ); - } - - _size = size; - - AttachmentsMap & attachments = _GetAttachments(); - - for (AttachmentsMap::value_type const& p : attachments) { - AttachmentRefPtr var = p.second; - - var->ResizeTexture(_size); - - _BindAttachment(var); - } -} - -void -GlfDrawTarget::_DeleteAttachments() -{ - // Can't delete the attachment textures while someone else is still holding - // onto them. - // XXX This code needs refactoring so that Attachment & AttachmentsContainer - // own the methods over their data (with casccading calls coming from the - // DrawTarget API). Checking for the RefPtr uniqueness is somewhat working - // against the nature of RefPtr.. - if (!_attachmentsPtr->IsUnique()) { - return; - } - - AttachmentsMap & attachments = _GetAttachments(); - - attachments.clear(); -} - -static int _GetMaxAttachments( ) -{ - int maxAttach = 0; - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxAttach); - return maxAttach; -} - -void -GlfDrawTarget::_GenFrameBuffer() -{ - _SaveBindingState(); - - _owningContext = GlfGLContext::GetCurrentGLContext(); - - // Create multisampled framebuffer - if (HasMSAA()) { - glGenFramebuffers(1, &_framebufferMS); - glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); - TF_VERIFY(glIsFramebuffer(_framebufferMS), - "Failed to allocate multisampled framebuffer"); - } - - // Create non-multisampled framebuffer - glGenFramebuffers(1, &_framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); - TF_VERIFY(glIsFramebuffer(_framebuffer), - "Failed to allocate framebuffer"); - - _RestoreBindingState(); -} - -GLuint -GlfDrawTarget::GetFramebufferId() const -{ - return _framebuffer; -} - -GLuint -GlfDrawTarget::GetFramebufferMSId() const -{ - return _framebufferMS; -} - -// Attach a texture to one of the attachment points of the framebuffer. -// We assume that the framebuffer is currently bound ! -void -GlfDrawTarget::_BindAttachment( GlfDrawTarget::AttachmentRefPtr const & a ) -{ - GLuint id = a->GetGlTextureName(); - GLuint idMS = a->GetGlTextureMSName(); - - int attach = a->GetAttach(); - - GLenum attachment = GL_COLOR_ATTACHMENT0; - if (a->GetFormat()==GL_DEPTH_COMPONENT) { - attachment = GL_DEPTH_ATTACHMENT; - } else if (a->GetFormat()==GL_DEPTH_STENCIL) { - attachment = GL_DEPTH_STENCIL_ATTACHMENT; - } else { - if (attach < 0) { - TF_CODING_ERROR("Attachment index cannot be negative"); - return; - } - - TF_VERIFY( attach < _GetMaxAttachments(), - "Exceeding number of Attachments available "); - - attachment += attach; - } - - GLint restoreFramebuffer = 0; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &restoreFramebuffer); - - // Multisampled framebuffer - if (HasMSAA()) { - glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); - glFramebufferTexture2D(GL_FRAMEBUFFER, - attachment, GL_TEXTURE_2D_MULTISAMPLE, idMS, /*level*/ 0); - } - - // Regular framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, - attachment, GL_TEXTURE_2D, id, /*level*/ 0); - - glBindFramebuffer(GL_FRAMEBUFFER, restoreFramebuffer); - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfDrawTarget::_SaveBindingState() -{ - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, - (GLint*)&_unbindRestoreReadFB); - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, - (GLint*)&_unbindRestoreDrawFB); -} - -void -GlfDrawTarget::_RestoreBindingState() -{ - glBindFramebuffer(GL_READ_FRAMEBUFFER, - _unbindRestoreReadFB); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, - _unbindRestoreDrawFB); -} - -void -GlfDrawTarget::Bind() -{ - if (++_bindDepth != 1) { - return; - } - - GLF_GROUP_FUNCTION(); - - _SaveBindingState(); - - // GL Frame buffer objects are not shared between - // contexts, So make sure we are on our owning context before we try to - // bind. The reason to test rather than switch is because the user's - // code may have setup other gl state and not expect a context switch here. - // Also the switch may be expensive, so we want to be explict about when - // they can occur. - if (!TF_VERIFY(_owningContext->IsCurrent())) { - return; - } - - if (HasMSAA()) { - glBindFramebuffer(GL_FRAMEBUFFER, _framebufferMS); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); - } - - GLF_POST_PENDING_GL_ERRORS(); -} - -bool -GlfDrawTarget::IsBound() const -{ - return (_bindDepth > 0); -} - -void -GlfDrawTarget::Unbind() -{ - if (--_bindDepth != 0) { - return; - } - GLF_GROUP_FUNCTION(); - - _RestoreBindingState(); - - TouchContents(); - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfDrawTarget::_Resolve() -{ - // Resolve MSAA fbo to a regular fbo - glBindFramebuffer(GL_READ_FRAMEBUFFER, _framebufferMS); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _framebuffer); - glBlitFramebuffer(0, 0, _size[0], _size[1], - 0, 0, _size[0], _size[1], - GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_STENCIL_BUFFER_BIT , - GL_NEAREST); -} - -void -GlfDrawTarget::Resolve() -{ - GLF_GROUP_FUNCTION(); - - if (HasMSAA()) { - _SaveBindingState(); - _Resolve(); - _RestoreBindingState(); - } -} - -/* static */ -void -GlfDrawTarget::Resolve(const std::vector& drawTargets) -{ - GLF_GROUP_FUNCTION(); - - bool anyResolved = false; - - for(GlfDrawTarget* dt : drawTargets) { - if (dt->HasMSAA()) { - if (!anyResolved) { - // If this is the first draw target to be resolved, - // save the old binding state. - anyResolved = true; - drawTargets[0]->_SaveBindingState(); - } - dt->_Resolve(); - } - } - - if (anyResolved) { - // If any draw targets were resolved, restore the old binding state. - drawTargets[0]->_RestoreBindingState(); - } -} - -void -GlfDrawTarget::TouchContents() -{ - AttachmentsMap const & attachments = GetAttachments(); - - for (AttachmentsMap::value_type const& p : attachments) { - p.second->TouchContents(); - } -} - -bool -GlfDrawTarget::IsValid(std::string * reason) -{ - return _Validate(reason); -} - -bool -GlfDrawTarget::_Validate(std::string * reason) -{ - if (!_framebuffer) { - return false; - } - - return GlfCheckGLFrameBufferStatus(GL_FRAMEBUFFER, reason); -} - -bool -GlfDrawTarget::WriteToFile(std::string const & name, - std::string const & filename, - GfMatrix4d const & viewMatrix, - GfMatrix4d const & projectionMatrix) -{ - TRACE_FUNCTION(); - - AttachmentsMap const & attachments = GetAttachments(); - AttachmentsMap::const_iterator it = attachments.find( name ); - - if (it==attachments.end()) { - TF_CODING_ERROR( "\""+name+"\" is not a valid variable name for this" - " DrawTarget" ); - return false; - } - - AttachmentRefPtr const & a = it->second; - - if (!_framebuffer) { - TF_CODING_ERROR( "DrawTarget has no framebuffer" ); - return false; - } - - int nelems = GlfGetNumElements(a->GetFormat()), - elemsize = GlfGetElementSize(a->GetType()), - stride = _size[0] * nelems * elemsize, - bufsize = _size[1] * stride; - - std::unique_ptr buf(new char[bufsize]); - - { - glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); - - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - - GLint restoreBinding, restoreActiveTexture; - glGetIntegerv( GL_TEXTURE_BINDING_2D, &restoreBinding ); - glGetIntegerv( GL_ACTIVE_TEXTURE, & restoreActiveTexture); - - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, a->GetGlTextureName() ); - - { - TRACE_FUNCTION_SCOPE("glGetTexImage"); - glGetTexImage(GL_TEXTURE_2D, 0, a->GetFormat(), a->GetType(), - buf.get()); - } - - glActiveTexture( restoreActiveTexture ); - glBindTexture( GL_TEXTURE_2D, restoreBinding ); - - glPopClientAttrib(); - } - - VtDictionary metadata; - - std::string ext = TfStringGetSuffix(filename); - if (name == "depth" && ext == "zfile") { - // transform depth value from normalized to camera space length - float *p = (float*)buf.get(); - for (size_t i = 0; i < bufsize/sizeof(float); ++i){ - p[i] = (float)(-2*p[i] / projectionMatrix[2][2]); - } - - // embed matrices into metadata - GfMatrix4d worldToCameraTransform = viewMatrix; - GfMatrix4d worldToScreenTransform = viewMatrix * projectionMatrix; - - GfMatrix4d invZ = GfMatrix4d().SetScale(GfVec3d(1, 1, -1)); - worldToCameraTransform *= invZ; - - metadata["Nl"] = worldToCameraTransform; - metadata["NP"] = worldToScreenTransform; - } - - GLenum glInternalFormat = a->GetInternalFormat(); - bool isSRGB = (glInternalFormat == GL_SRGB8 || - glInternalFormat == GL_SRGB8_ALPHA8); - HioImage::StorageSpec storage; - storage.width = _size[0]; - storage.height = _size[1]; - storage.format = GlfGetHioFormat(a->GetFormat(), - a->GetType(), - /* isSRGB */ isSRGB); - storage.flipped = true; - storage.data = buf.get(); - - { - TRACE_FUNCTION_SCOPE("writing image"); - - HioImageSharedPtr const image = HioImage::OpenForWriting(filename); - const bool writeSuccess = image && image->Write(storage, metadata); - - if (!writeSuccess) { - TF_RUNTIME_ERROR("Failed to write image to %s", filename.c_str()); - return false; - } - } - - GLF_POST_PENDING_GL_ERRORS(); - - return true; -} - -//---------------------------------------------------------------------- - -GlfDrawTarget::AttachmentRefPtr -GlfDrawTarget::Attachment::New(int glIndex, GLenum format, GLenum type, - GLenum internalFormat, GfVec2i size, - unsigned int numSamples) -{ - return TfCreateRefPtr(new Attachment(glIndex, format, type, - internalFormat, size, - numSamples)); -} - -GlfDrawTarget::Attachment::Attachment(int glIndex, GLenum format, - GLenum type, GLenum internalFormat, - GfVec2i size, - unsigned int numSamples) : - _textureName(0), - _textureNameMS(0), - _format(format), - _type(type), - _internalFormat(internalFormat), - _glIndex(glIndex), - _size(size), - _numSamples(numSamples) -{ - _GenTexture(); -} - -GlfDrawTarget::Attachment::~Attachment() -{ - _DeleteTexture(); -} - -// Generate a simple GL_TEXTURE_2D to use as an attachment -// we assume that the framebuffer is currently bound ! -void -GlfDrawTarget::Attachment::_GenTexture() -{ - HF_MALLOC_TAG_FUNCTION(); - - GLenum internalFormat = _internalFormat; - GLenum type = _type; - size_t memoryUsed = 0; - - if (_format==GL_DEPTH_COMPONENT) { - internalFormat=GL_DEPTH_COMPONENT32F; - if (type!=GL_FLOAT) { - TF_CODING_ERROR("Only GL_FLOAT textures can be used for the" - " depth attachment point"); - type = GL_FLOAT; - } - } - - int bytePerPixel = (_type == GL_FLOAT) ? 4 : 1; - int numChannel; - switch (_format) - { - case GL_RG: - numChannel = 2; - break; - - case GL_RGB: - numChannel = 3; - break; - - case GL_RGBA: - numChannel = 4; - break; - - default: - numChannel = 1; - } - - size_t baseImageSize = (size_t)(bytePerPixel * - numChannel * - _size[0] * - _size[1]); - - // Create multisampled texture - if (_numSamples > 1) { - glGenTextures( 1, &_textureNameMS ); - glBindTexture( GL_TEXTURE_2D_MULTISAMPLE, _textureNameMS ); - - // XXX: Hardcoded filtering for now - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, - _numSamples, _internalFormat, - _size[0], _size[1], GL_TRUE ); - - glBindTexture( GL_TEXTURE_2D_MULTISAMPLE, 0); - - memoryUsed = baseImageSize * _numSamples; - } - - // Create non-multisampled texture - glGenTextures( 1, &_textureName ); - glBindTexture( GL_TEXTURE_2D, _textureName ); - - // XXX: Hardcoded filtering for now - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - glTexImage2D( GL_TEXTURE_2D, /*level*/ 0, internalFormat, - _size[0], _size[1], - /*border*/ 0, _format, type, NULL); - - glBindTexture( GL_TEXTURE_2D, 0 ); - - memoryUsed += baseImageSize; - - _SetMemoryUsed(memoryUsed); - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfDrawTarget::Attachment::_DeleteTexture() -{ - if (_textureName) { - GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; - - TF_VERIFY(glIsTexture(_textureName), "Tried to delete an invalid texture"); - glDeleteTextures(1, &_textureName); - _textureName = 0; - } - - if (_textureNameMS) { - GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; - - TF_VERIFY(glIsTexture(_textureNameMS), "Tried to delete an invalid texture"); - glDeleteTextures(1, &_textureNameMS); - _textureNameMS = 0; - } - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfDrawTarget::Attachment::ResizeTexture(const GfVec2i &size) -{ - _size = size; - - _DeleteTexture(); - _GenTexture(); -} - -/* virtual */ -GlfTexture::BindingVector -GlfDrawTarget::Attachment::GetBindings(TfToken const & identifier, - GLuint samplerName) -{ - return BindingVector(1, - Binding(identifier, GlfTextureTokens->texels, - GL_TEXTURE_2D, GetGlTextureName(), samplerName)); -} - -GLuint -GlfDrawTarget::Attachment::GetGlTextureName() -{ - return _textureName; -} - -/* virtual */ -VtDictionary -GlfDrawTarget::Attachment::GetTextureInfo(bool forceLoad) -{ - TF_UNUSED(forceLoad); - - VtDictionary info; - - info["width"] = (int)_size[0]; - info["height"] = (int)_size[1]; - info["memoryUsed"] = GetMemoryUsed(); - info["depth"] = 1; - info["format"] = (int)_internalFormat; - info["imageFilePath"] = TfToken("DrawTarget"); - info["referenceCount"] = GetCurrentCount(); - info["numSamples"] = _numSamples; - - return info; -} - -void -GlfDrawTarget::Attachment::TouchContents() -{ - _UpdateContentsID(); -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/glContext.cpp b/Sources/OpenUSD/imaging/glf/glContext.cpp deleted file mode 100644 index 782118ea63..0000000000 --- a/Sources/OpenUSD/imaging/glf/glContext.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#include "pxr/imaging/glf/glContext.h" -#include "pxr/imaging/glf/glContextRegistry.h" -#include "pxr/imaging/garch/glPlatformContext.h" - -#include "pxr/base/trace/trace.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -// -// GlfGLContext -// - -GlfGLContext::GlfGLContext() -{ - // Do nothing -} - -GlfGLContext::~GlfGLContext() -{ - GlfGLContextRegistry::GetInstance().Remove(this); -} - -GlfGLContextSharedPtr -GlfGLContext::GetCurrentGLContext() -{ - return GlfGLContextRegistry::GetInstance().GetCurrent(); -} - -GlfGLContextSharedPtr -GlfGLContext::GetSharedGLContext() -{ - return GlfGLContextRegistry::GetInstance().GetShared(); -} - -void -GlfGLContext::MakeCurrent(const GlfGLContextSharedPtr& context) -{ - TRACE_FUNCTION(); - - if (context && context->IsValid()) { - context->_MakeCurrent(); - - // Now that this context is current add it to the registry for - // later lookup. - GlfGLContextRegistry::GetInstance().DidMakeCurrent(context); - } - else { - DoneCurrent(); - } -} - -bool -GlfGLContext::AreSharing(GlfGLContextSharedPtr const & context1, - GlfGLContextSharedPtr const & context2) -{ - return (context1 && context1->IsSharing(context2)); -} - -bool -GlfGLContext::IsInitialized() -{ - return GlfGLContextRegistry::GetInstance().IsInitialized(); -} - -bool -GlfGLContext::IsCurrent() const -{ - return IsValid() && _IsEqual(GetCurrentGLContext()); -} - -void -GlfGLContext::MakeCurrent() -{ - if (IsValid()) { - _MakeCurrent(); - } -} - -void -GlfGLContext::DoneCurrent() -{ - GarchGLPlatformContextState::DoneCurrent(); -} - -bool -GlfGLContext::IsSharing(GlfGLContextSharedPtr const & otherContext) -{ - return otherContext && IsValid() && - otherContext->IsValid() && _IsSharing(otherContext); -} - -// -// GlfGLContextScopeHolder -// - -GlfGLContextScopeHolder::GlfGLContextScopeHolder( - const GlfGLContextSharedPtr& newContext) : - _newContext(newContext) -{ - if (_newContext) { - _oldContext = GlfGLContext::GetCurrentGLContext(); - } - _MakeNewContextCurrent(); -} - -GlfGLContextScopeHolder::~GlfGLContextScopeHolder() -{ - _RestoreOldContext(); -} - -void -GlfGLContextScopeHolder::_MakeNewContextCurrent() -{ - if (_newContext) { - GlfGLContext::MakeCurrent(_newContext); - } -} - -void -GlfGLContextScopeHolder::_RestoreOldContext() -{ - if (_newContext) { - GlfGLContext::MakeCurrent(_oldContext); - } -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/glContextRegistry.cpp b/Sources/OpenUSD/imaging/glf/glContextRegistry.cpp deleted file mode 100644 index 2224163c8e..0000000000 --- a/Sources/OpenUSD/imaging/glf/glContextRegistry.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -/// \file glContextRegistry.cpp - -#include "pxr/imaging/glf/glContextRegistry.h" -#include "pxr/imaging/glf/glRawContext.h" -#include "pxr/imaging/garch/glPlatformContext.h" -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/instantiateSingleton.h" -#include -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -typedef std::weak_ptr GlfGLContextWeakPtr; - -static GlfGLContextSharedPtr _nullContext; - -TF_INSTANTIATE_SINGLETON(GlfGLContextRegistry); - -// -// GlfGLContextRegistry_Data -// - -struct GlfGLContextRegistry_Data { - typedef std::unordered_map ContextsByState; - typedef std::map StatesByContext; - - ContextsByState contextsByState; - StatesByContext statesByContext; -}; - -// -// GlfGLContextRegistry -// - -GlfGLContextRegistry::GlfGLContextRegistry() : - _sharedContextInitialized(false), - _data(new GlfGLContextRegistry_Data) -{ - // Make a context for when no context is bound. This is to avoid - // repeatedly creating a raw context for this condition in GetCurrent(). - GarchGLPlatformContextState nullState=GarchGetNullGLPlatformContextState(); - _nullContext = GlfGLRawContext::New(nullState); - _data->contextsByState[nullState] = _nullContext; - _data->statesByContext[_nullContext.get()] = nullState; -} - -GlfGLContextRegistry::~GlfGLContextRegistry() -{ - _nullContext.reset(); -} - -bool -GlfGLContextRegistry::IsInitialized() const -{ - return !_interfaces.empty(); -} - -void -GlfGLContextRegistry::Add(GlfGLContextRegistrationInterface* iface) -{ - if (TF_VERIFY(iface, "NULL GlfGLContextRegistrationInterface")) { - _interfaces.emplace_back(iface); - } -} - -GlfGLContextSharedPtr -GlfGLContextRegistry::GetShared() -{ - if (!_sharedContextInitialized) { - - // Don't do this again. - _sharedContextInitialized = true; - - _shared = GlfGLContextSharedPtr(); - - // Find the first interface with a shared context. - for (std::unique_ptr &iface : - _interfaces) { - if (GlfGLContextSharedPtr shared = iface->GetShared()) { - _shared = shared; - return _shared; - } - } - - TF_CODING_ERROR("No shared context registered."); - } - return _shared; -} - -GlfGLContextSharedPtr -GlfGLContextRegistry::GetCurrent() -{ - // Get the current raw state. - GarchGLPlatformContextState rawState; - - // See if we know a context with this raw state. - GlfGLContextRegistry_Data::ContextsByState::iterator i = - _data->contextsByState.find(rawState); - if (i != _data->contextsByState.end()) { - // Promote weak to shared. - return GlfGLContextSharedPtr(i->second); - } - - // We don't know this raw state. Try syncing each interface to see - // if any system thinks this state is current. - for (std::unique_ptr &iface - : _interfaces) { - if (GlfGLContextSharedPtr currentContext = iface->GetCurrent()) { - if (currentContext->IsValid()) { - GlfGLContext::MakeCurrent(currentContext); - GarchGLPlatformContextState currentRawState; - if (rawState == currentRawState) { - // Yes, currentContext has the raw state we're looking - // for. GlfGLContext::MakeCurrent() has already called - // DidMakeCurrent() so this context is now registered - // in case we need to look it up again. - return currentContext; - } - } - } - } - - // We can't find this state. We'll return the raw context as a fallback. - // Note that the raw context's IsValid() will not go false when the - // context is destroyed. This is why we prefer a non-raw state. - rawState.MakeCurrent(); - return GlfGLRawContext::New(rawState); -} - -void -GlfGLContextRegistry::DidMakeCurrent(const GlfGLContextSharedPtr& context) -{ - // If we already know about this context then do nothing. If we don't - // but we already know about this state then still do nothing. - if (_data->statesByContext.find(context.get()) == - _data->statesByContext.end()) { - GarchGLPlatformContextState currentState; - if (_data->contextsByState.find(currentState) == - _data->contextsByState.end()) { - // Register context under the current context state. - _data->contextsByState[currentState] = context; - _data->statesByContext[context.get()] = currentState; - } - } -} - -void -GlfGLContextRegistry::Remove(const GlfGLContext* context) -{ - GlfGLContextRegistry_Data::StatesByContext::iterator i = - _data->statesByContext.find(context); - if (i != _data->statesByContext.end()) { - TF_VERIFY(_data->contextsByState.erase(i->second)); - _data->statesByContext.erase(i); - } -} - -// -// GlfGLContextRegistrationInterface -// - -GlfGLContextRegistrationInterface::GlfGLContextRegistrationInterface() -{ - // Register ourself. - GlfGLContextRegistry::GetInstance().Add(this); -} - -GlfGLContextRegistrationInterface::~GlfGLContextRegistrationInterface() -{ - // Do nothing -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/overview.dox b/Sources/OpenUSD/imaging/glf/overview.dox deleted file mode 100644 index 6a07319683..0000000000 --- a/Sources/OpenUSD/imaging/glf/overview.dox +++ /dev/null @@ -1,9 +0,0 @@ -/*! -\page glf_page_front Glf: Utility classes for OpenGL -\if ( PIXAR_MFB_BUILD ) -\mainpage Glf: Utility classes for OpenGL -\endif - -Utility classes for OpenGL output. - -*/ diff --git a/Sources/OpenUSD/imaging/glf/plugInfo.json b/Sources/OpenUSD/imaging/glf/plugInfo.json deleted file mode 100644 index 6b9020aac6..0000000000 --- a/Sources/OpenUSD/imaging/glf/plugInfo.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Plugins": [ - { - "Info": { - "ShaderResources": "shaders" - }, - "LibraryPath": "@PLUG_INFO_LIBRARY_PATH@", - "Name": "glf", - "ResourcePath": "@PLUG_INFO_RESOURCE_PATH@", - "Root": "@PLUG_INFO_ROOT@", - "Type": "library" - } - ] -} diff --git a/Sources/OpenUSD/imaging/glf/simpleLight.cpp b/Sources/OpenUSD/imaging/glf/simpleLight.cpp deleted file mode 100644 index 41b770ca97..0000000000 --- a/Sources/OpenUSD/imaging/glf/simpleLight.cpp +++ /dev/null @@ -1,418 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -/// \file simpleLight.cpp - -#include "pxr/imaging/glf/simpleLight.h" - -#include "pxr/imaging/garch/glApi.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -GlfSimpleLight::GlfSimpleLight(GfVec4f const & position) : - _ambient(0.2, 0.2, 0.2, 1.0), - _diffuse(1.0, 1.0, 1.0, 1.0), - _specular(1.0, 1.0, 1.0, 1.0), - _position(position[0], position[1], position[2], 1.0), - _spotDirection(0.0, 0.0, -1.0), - _spotCutoff(180.0), - _spotFalloff(0.0), - _attenuation(1.0, 0.0, 0.0), - _isCameraSpaceLight(false), - _hasIntensity(true), - _hasShadow(false), - _shadowResolution(512), - _shadowBias(0.0), - _shadowBlur(0.0), - _shadowIndexStart(0), - _shadowIndexEnd(0), - _transform(GfMatrix4d().SetIdentity()), - _shadowMatrices(std::vector(1, GfMatrix4d().SetIdentity())), - _isDomeLight(false), - _id() -{ -} - -GlfSimpleLight::~GlfSimpleLight() = default; - -GfMatrix4d const & -GlfSimpleLight::GetTransform() const -{ - return _transform; -} - -void -GlfSimpleLight::SetTransform(GfMatrix4d const & mat) -{ - _transform = mat; -} - -GfVec4f const & -GlfSimpleLight::GetAmbient() const -{ - return _ambient; -} - -void -GlfSimpleLight::SetAmbient(GfVec4f const & ambient) -{ - _ambient = ambient; -} - - -GfVec4f const & -GlfSimpleLight::GetDiffuse() const -{ - return _diffuse; -} - -void -GlfSimpleLight::SetDiffuse(GfVec4f const & diffuse) -{ - _diffuse = diffuse; -} - - -GfVec4f const & -GlfSimpleLight::GetSpecular() const -{ - return _specular; -} - -void -GlfSimpleLight::SetSpecular(GfVec4f const & specular) -{ - _specular = specular; -} - -GfVec4f const & -GlfSimpleLight::GetPosition() const -{ - return _position; -} - -void -GlfSimpleLight::SetPosition(GfVec4f const & position) -{ - _position = position; -} - -GfVec3f const & -GlfSimpleLight::GetSpotDirection() const -{ - return _spotDirection; -} - -void -GlfSimpleLight::SetSpotDirection(GfVec3f const & spotDirection) -{ - _spotDirection = spotDirection; -} - -float const & -GlfSimpleLight::GetSpotCutoff() const -{ - return _spotCutoff; -} - -void -GlfSimpleLight::SetSpotCutoff(float const & spotCutoff) -{ - _spotCutoff = spotCutoff; -} - -float const & -GlfSimpleLight::GetSpotFalloff() const -{ - return _spotFalloff; -} - -void -GlfSimpleLight::SetSpotFalloff(float const & spotFalloff) -{ - _spotFalloff = spotFalloff; -} - -GfVec3f const & -GlfSimpleLight::GetAttenuation() const -{ - return _attenuation; -} - -void -GlfSimpleLight::SetAttenuation(GfVec3f const & attenuation) -{ - _attenuation = attenuation; -} - -void -GlfSimpleLight::SetHasIntensity(bool hasIntensity) -{ - _hasIntensity = hasIntensity; -} - -bool -GlfSimpleLight::HasIntensity() const -{ - return _hasIntensity; -} - -bool -GlfSimpleLight::HasShadow() const -{ - return _hasShadow; -} - -void -GlfSimpleLight::SetHasShadow(bool hasShadow) -{ - _hasShadow = hasShadow; -} - -int -GlfSimpleLight::GetShadowResolution() const -{ - return _shadowResolution; -} - -void -GlfSimpleLight::SetShadowResolution(int resolution) -{ - _shadowResolution = resolution; -} - -float -GlfSimpleLight::GetShadowBias() const -{ - return _shadowBias; -} - -void -GlfSimpleLight::SetShadowBias(float bias) -{ - _shadowBias = bias; -} - -float -GlfSimpleLight::GetShadowBlur() const -{ - return _shadowBlur; -} - -void -GlfSimpleLight::SetShadowBlur(float blur) -{ - _shadowBlur = blur; -} - -int -GlfSimpleLight::GetShadowIndexStart() const -{ - return _shadowIndexStart; -} - -void -GlfSimpleLight::SetShadowIndexStart(int shadowStart) -{ - _shadowIndexStart = shadowStart; -} - -int -GlfSimpleLight::GetShadowIndexEnd() const -{ - return _shadowIndexEnd; -} - -void -GlfSimpleLight::SetShadowIndexEnd(int shadowEnd) -{ - _shadowIndexEnd = shadowEnd; -} - -std::vector const & -GlfSimpleLight::GetShadowMatrices() const -{ - return _shadowMatrices; -} - -void -GlfSimpleLight::SetShadowMatrices(std::vector const & matrices) -{ - _shadowMatrices = matrices; -} - -bool -GlfSimpleLight::IsCameraSpaceLight() const -{ - return _isCameraSpaceLight; -} - -void -GlfSimpleLight::SetIsCameraSpaceLight(bool isCameraSpaceLight) -{ - _isCameraSpaceLight = isCameraSpaceLight; -} - -SdfPath const & -GlfSimpleLight::GetID() const -{ - return _id; -} - -void GlfSimpleLight::SetID(SdfPath const & id) -{ - _id = id; -} - -bool -GlfSimpleLight::IsDomeLight() const -{ - return _isDomeLight; -} - -void -GlfSimpleLight::SetIsDomeLight(bool isDomeLight) -{ - _isDomeLight = isDomeLight; -} - -const SdfAssetPath & -GlfSimpleLight::GetDomeLightTextureFile() const -{ - return _domeLightTextureFile; -} - -void -GlfSimpleLight::SetDomeLightTextureFile(const SdfAssetPath &path) -{ - _domeLightTextureFile = path; -} - -TfToken const & -GlfSimpleLight::GetPostSurfaceIdentifier() const -{ - return _postSurfaceIdentifier; -} - -std::string const & -GlfSimpleLight::GetPostSurfaceShaderSource() const -{ - return _postSurfaceShaderSource; -} - - -VtUCharArray const & -GlfSimpleLight::GetPostSurfaceShaderParams() const -{ - return _postSurfaceShaderParams; -} - -void -GlfSimpleLight::SetPostSurfaceParams(TfToken const & identifier, - std::string const & shaderSource, - VtUCharArray const & shaderParams) -{ - _postSurfaceIdentifier = identifier; - _postSurfaceShaderSource = shaderSource; - _postSurfaceShaderParams = shaderParams; -} - -// -------------------------------------------------------------------------- // -// VtValue requirements -// -------------------------------------------------------------------------- // - -bool -GlfSimpleLight::operator==(const GlfSimpleLight& other) const -{ - return _ambient == other._ambient - && _diffuse == other._diffuse - && _specular == other._specular - && _position == other._position - && _spotDirection == other._spotDirection - && _spotCutoff == other._spotCutoff - && _spotFalloff == other._spotFalloff - && _attenuation == other._attenuation - && _hasIntensity == other._hasIntensity - && _hasShadow == other._hasShadow - && _shadowResolution == other._shadowResolution - && _shadowBias == other._shadowBias - && _shadowBlur == other._shadowBlur - && _shadowIndexStart == other._shadowIndexStart - && _shadowIndexEnd == other._shadowIndexEnd - && _transform == other._transform - && _shadowMatrices == other._shadowMatrices - && _isCameraSpaceLight == other._isCameraSpaceLight - && _isDomeLight == other._isDomeLight - && _domeLightTextureFile == other._domeLightTextureFile - && _postSurfaceIdentifier == other._postSurfaceIdentifier - && _postSurfaceShaderSource == other._postSurfaceShaderSource - && _postSurfaceShaderParams == other._postSurfaceShaderParams - && _id == other._id; -} - -bool -GlfSimpleLight::operator!=(const GlfSimpleLight& other) const -{ - return !(*this == other); -} - -std::ostream& operator<<(std::ostream& out, const GlfSimpleLight& v) -{ - out << v._ambient - << v._diffuse - << v._specular - << v._position - << v._spotDirection - << v._spotCutoff - << v._spotFalloff - << v._attenuation - << v._hasIntensity - << v._hasShadow - << v._shadowResolution - << v._shadowBias - << v._shadowBlur - << v._shadowIndexStart - << v._shadowIndexEnd - << v._transform - << v._isCameraSpaceLight - << v._isDomeLight - << v._domeLightTextureFile - << v._postSurfaceIdentifier - << v._postSurfaceShaderSource - << v._postSurfaceShaderParams - << v._id; - for (auto const& m : v._shadowMatrices) { - out << m; - } - return out; -} - -std::ostream& -operator<<(std::ostream& out, const GlfSimpleLightVector& pv) -{ - return out; -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/simpleLightingContext.cpp b/Sources/OpenUSD/imaging/glf/simpleLightingContext.cpp deleted file mode 100644 index 613090f438..0000000000 --- a/Sources/OpenUSD/imaging/glf/simpleLightingContext.cpp +++ /dev/null @@ -1,782 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -/// \file simpleLightingContext.cpp - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/simpleLightingContext.h" -#include "pxr/imaging/glf/bindingMap.h" -#include "pxr/imaging/glf/debugCodes.h" -#include "pxr/imaging/glf/diagnostic.h" -#include "pxr/imaging/glf/simpleLight.h" -#include "pxr/imaging/glf/simpleMaterial.h" -#include "pxr/imaging/glf/uniformBlock.h" - -#include "pxr/imaging/hio/glslfx.h" - -#include "pxr/base/arch/hash.h" -#include "pxr/base/arch/pragmas.h" -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/stringUtils.h" -#include "pxr/base/tf/staticData.h" -#include "pxr/base/tf/staticTokens.h" - -#include "pxr/base/trace/trace.h" - -#include -#include -#include -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_DEFINE_PRIVATE_TOKENS( - _tokens, - ((lightingUB, "Lighting")) - ((shadowUB, "Shadow")) - ((materialUB, "Material")) - ((postSurfaceShaderUB, "PostSurfaceShaderParams")) - ((shadowCompareTextures, "shadowCompareTextures")) -); - -/* static */ -GlfSimpleLightingContextRefPtr -GlfSimpleLightingContext::New() -{ - return TfCreateRefPtr(new This()); -} - -GlfSimpleLightingContext::GlfSimpleLightingContext() : - _shadows(TfCreateRefPtr(new GlfSimpleShadowArray())), - _worldToViewMatrix(1.0), - _projectionMatrix(1.0), - _sceneAmbient(0.01, 0.01, 0.01, 1.0), - _useLighting(false), - _useShadows(false), - _useColorMaterialDiffuse(false), - _lightingUniformBlockValid(false), - _shadowUniformBlockValid(false), - _materialUniformBlockValid(false), - _postSurfaceShaderStateValid(false) -{ -} - -GlfSimpleLightingContext::~GlfSimpleLightingContext() -{ -} - -void -GlfSimpleLightingContext::SetLights(GlfSimpleLightVector const & lights) -{ - _lights = lights; - _lightingUniformBlockValid = false; - _shadowUniformBlockValid = false; - _postSurfaceShaderStateValid = false; - - int numLights = GetNumLightsUsed(); - - _useShadows = false; - for (int i = 0;i < numLights; ++i) { - if (_lights[i].HasShadow()) { - _useShadows = true; - break; - } - } -} - -const GlfSimpleLightVector & -GlfSimpleLightingContext::GetLights() const -{ - return _lights; -} - -int -GlfSimpleLightingContext::GetNumLightsUsed() const -{ - return (int)_lights.size(); -} - -int -GlfSimpleLightingContext::ComputeNumShadowsUsed() const -{ - int numShadows = 0; - for (auto const& light : _lights) { - if (light.HasShadow() && numShadows <= light.GetShadowIndexEnd()) { - numShadows = light.GetShadowIndexEnd() + 1; - } - } - return numShadows; -} - -void -GlfSimpleLightingContext::SetShadows(GlfSimpleShadowArrayRefPtr const & shadows) -{ - _shadows = shadows; - _shadowUniformBlockValid = false; -} - -GlfSimpleShadowArrayRefPtr const & -GlfSimpleLightingContext::GetShadows() const -{ - return _shadows; -} - -void -GlfSimpleLightingContext::SetMaterial(GlfSimpleMaterial const & material) -{ - if (_material != material) { - _material = material; - _materialUniformBlockValid = false; - } -} - -GlfSimpleMaterial const & -GlfSimpleLightingContext::GetMaterial() const -{ - return _material; -} - -void -GlfSimpleLightingContext::SetSceneAmbient(GfVec4f const & sceneAmbient) -{ - if (_sceneAmbient != sceneAmbient) { - _sceneAmbient = sceneAmbient; - _materialUniformBlockValid = false; - } -} - -GfVec4f const & -GlfSimpleLightingContext::GetSceneAmbient() const -{ - return _sceneAmbient; -} - -void -GlfSimpleLightingContext::SetCamera(GfMatrix4d const &worldToViewMatrix, - GfMatrix4d const &projectionMatrix) -{ - if (_worldToViewMatrix != worldToViewMatrix) { - _worldToViewMatrix = worldToViewMatrix; - _lightingUniformBlockValid = false; - _shadowUniformBlockValid = false; - } - _projectionMatrix = projectionMatrix; -} - -void -GlfSimpleLightingContext::SetUseLighting(bool val) -{ - if (_useLighting != val) { - _useLighting = val; - _lightingUniformBlockValid = false; - } -} - -bool -GlfSimpleLightingContext::GetUseLighting() const -{ - return _useLighting; -} - -bool -GlfSimpleLightingContext::GetUseShadows() const -{ - return _useShadows; -} - -void -GlfSimpleLightingContext::SetUseColorMaterialDiffuse(bool val) -{ - if (_useColorMaterialDiffuse != val) { - _lightingUniformBlockValid = false; - _useColorMaterialDiffuse = val; - } -} - -bool -GlfSimpleLightingContext::GetUseColorMaterialDiffuse() const -{ - return _useColorMaterialDiffuse; -} - -void -GlfSimpleLightingContext::InitUniformBlockBindings( - GlfBindingMapPtr const &bindingMap) const -{ - // populate uniform bindings (XXX: need better API) - bindingMap->GetUniformBinding(_tokens->lightingUB); - bindingMap->GetUniformBinding(_tokens->shadowUB); - bindingMap->GetUniformBinding(_tokens->materialUB); - bindingMap->GetUniformBinding(_tokens->postSurfaceShaderUB); -} - -void -GlfSimpleLightingContext::InitSamplerUnitBindings( - GlfBindingMapPtr const &bindingMap) const -{ - size_t const numShadows = _shadows->GetNumShadowMapPasses(); - for (size_t i = 0; i < numShadows; ++i) { - bindingMap->GetSamplerUnit( - TfStringPrintf("%s[%zd]", - _tokens->shadowCompareTextures.GetText(), i)); - } -} - -inline void -setVec3(float *dst, GfVec3f const & vec) -{ - dst[0] = vec[0]; - dst[1] = vec[1]; - dst[2] = vec[2]; -} - -inline static void -setVec4(float *dst, GfVec4f const &vec) -{ - dst[0] = vec[0]; - dst[1] = vec[1]; - dst[2] = vec[2]; - dst[3] = vec[3]; -} - -inline static void -setMatrix(float *dst, GfMatrix4d const & mat) -{ - for (int i = 0; i < 4; ++i) - for (int j = 0; j < 4; ++j) - dst[i*4+j] = (float)mat[i][j]; -} - -void -GlfSimpleLightingContext::BindUniformBlocks(GlfBindingMapPtr const &bindingMap) -{ - GLF_GROUP_FUNCTION(); - - if (!_lightingUniformBlock) - _lightingUniformBlock = GlfUniformBlock::New("_lightingUniformBlock"); - if (!_shadowUniformBlock) - _shadowUniformBlock = GlfUniformBlock::New("_shadowUniformBlock"); - if (!_materialUniformBlock) - _materialUniformBlock = GlfUniformBlock::New("_materialUniformBlock"); - - bool shadowExists = false; - if ((!_lightingUniformBlockValid || - !_shadowUniformBlockValid) && _lights.size() > 0) { - int numLights = GetNumLightsUsed(); - int numShadows = ComputeNumShadowsUsed(); - - // 16byte aligned - struct LightSource { - float position[4]; - float ambient[4]; - float diffuse[4]; - float specular[4]; - float spotDirection[4]; - float spotCutoff; - float spotFalloff; - float padding[2]; - float attenuation[4]; - float worldToLightTransform[16]; - int32_t shadowIndexStart; - int32_t shadowIndexEnd; - int32_t hasShadow; - int32_t isIndirectLight; - }; - - struct Lighting { - int32_t useLighting; - int32_t useColorMaterialDiffuse; - int32_t padding[2]; - ARCH_PRAGMA_PUSH - ARCH_PRAGMA_ZERO_SIZED_STRUCT - LightSource lightSource[0]; - ARCH_PRAGMA_POP - }; - - // 16byte aligned - struct ShadowMatrix { - float viewToShadowMatrix[16]; - float shadowToViewMatrix[16]; - float blur; - float bias; - float padding[2]; - }; - - struct Shadow { - ARCH_PRAGMA_PUSH - ARCH_PRAGMA_ZERO_SIZED_STRUCT - ShadowMatrix shadow[0]; - ARCH_PRAGMA_POP - }; - - size_t lightingSize = sizeof(Lighting) + sizeof(LightSource) * numLights; - size_t shadowSize = sizeof(ShadowMatrix) * numShadows; - Lighting *lightingData = (Lighting *)alloca(lightingSize); - Shadow *shadowData = (Shadow *)alloca(shadowSize); - memset(shadowData, 0, shadowSize); - memset(lightingData, 0, lightingSize); - - GfMatrix4d viewToWorldMatrix = _worldToViewMatrix.GetInverse(); - - lightingData->useLighting = _useLighting; - lightingData->useColorMaterialDiffuse = _useColorMaterialDiffuse; - - for (int i = 0; _useLighting && i < numLights; ++i) { - GlfSimpleLight const &light = _lights[i]; - - setVec4(lightingData->lightSource[i].position, - light.GetPosition() * _worldToViewMatrix); - setVec4(lightingData->lightSource[i].diffuse, light.GetDiffuse()); - setVec4(lightingData->lightSource[i].ambient, light.GetAmbient()); - setVec4(lightingData->lightSource[i].specular, light.GetSpecular()); - setVec3(lightingData->lightSource[i].spotDirection, - _worldToViewMatrix.TransformDir(light.GetSpotDirection())); - setVec3(lightingData->lightSource[i].attenuation, - light.GetAttenuation()); - lightingData->lightSource[i].spotCutoff = light.GetSpotCutoff(); - lightingData->lightSource[i].spotFalloff = light.GetSpotFalloff(); - setMatrix(lightingData->lightSource[i].worldToLightTransform, - light.GetTransform().GetInverse()); - lightingData->lightSource[i].hasShadow = light.HasShadow(); - lightingData->lightSource[i].isIndirectLight = light.IsDomeLight(); - - if (lightingData->lightSource[i].hasShadow) { - int shadowIndexStart = light.GetShadowIndexStart(); - lightingData->lightSource[i].shadowIndexStart = - shadowIndexStart; - int shadowIndexEnd = light.GetShadowIndexEnd(); - lightingData->lightSource[i].shadowIndexEnd = shadowIndexEnd; - - for (int shadowIndex = shadowIndexStart; - shadowIndex <= shadowIndexEnd; ++shadowIndex) { - GfMatrix4d viewToShadowMatrix = viewToWorldMatrix * - _shadows->GetWorldToShadowMatrix(shadowIndex); - GfMatrix4d shadowToViewMatrix = - viewToShadowMatrix.GetInverse(); - - shadowData->shadow[shadowIndex].bias = light.GetShadowBias(); - shadowData->shadow[shadowIndex].blur = light.GetShadowBlur(); - - setMatrix( - shadowData->shadow[shadowIndex].viewToShadowMatrix, - viewToShadowMatrix); - setMatrix( - shadowData->shadow[shadowIndex].shadowToViewMatrix, - shadowToViewMatrix); - } - - shadowExists = true; - } - } - - _lightingUniformBlock->Update(lightingData, lightingSize); - _lightingUniformBlockValid = true; - - if (shadowExists) { - _shadowUniformBlock->Update(shadowData, shadowSize); - _shadowUniformBlockValid = true; - } - } - - _lightingUniformBlock->Bind(bindingMap, _tokens->lightingUB); - - if (shadowExists) { - _shadowUniformBlock->Bind(bindingMap, _tokens->shadowUB); - } - - if (!_materialUniformBlockValid) { - // has to be matched with the definition of simpleLightingShader.glslfx - struct Material { - float ambient[4]; - float diffuse[4]; - float specular[4]; - float emission[4]; - float sceneColor[4]; // XXX: should be separated? - float shininess; - float padding[3]; - } materialData; - - memset(&materialData, 0, sizeof(materialData)); - - setVec4(materialData.ambient, _material.GetAmbient()); - setVec4(materialData.diffuse, _material.GetDiffuse()); - setVec4(materialData.specular, _material.GetSpecular()); - setVec4(materialData.emission, _material.GetEmission()); - materialData.shininess = _material.GetShininess(); - setVec4(materialData.sceneColor, _sceneAmbient); - - _materialUniformBlock->Update(&materialData, sizeof(materialData)); - _materialUniformBlockValid = true; - } - - _materialUniformBlock->Bind(bindingMap, _tokens->materialUB); - - _BindPostSurfaceShaderParams(bindingMap); -} - -void -GlfSimpleLightingContext::BindSamplers(GlfBindingMapPtr const &bindingMap) -{ - size_t const numShadows = _shadows->GetNumShadowMapPasses(); - for (size_t i = 0; i < numShadows; ++i) { - std::string samplerName = - TfStringPrintf("%s[%zd]", - _tokens->shadowCompareTextures.GetText(), i); - int shadowSampler = bindingMap->GetSamplerUnit(samplerName); - - glActiveTexture(GL_TEXTURE0 + shadowSampler); - glBindTexture(GL_TEXTURE_2D, _shadows->GetShadowMapTexture(i)); - glBindSampler(shadowSampler, _shadows->GetShadowMapCompareSampler()); - } - - glActiveTexture(GL_TEXTURE0); -} - -void -GlfSimpleLightingContext::UnbindSamplers(GlfBindingMapPtr const &bindingMap) -{ - size_t const numShadows = _shadows->GetNumShadowMapPasses(); - for (size_t i = 0; i < numShadows; ++i) { - std::string samplerName = - TfStringPrintf("%s[%zd]", - _tokens->shadowCompareTextures.GetText(), i); - int shadowSampler = bindingMap->GetSamplerUnit(samplerName); - - glActiveTexture(GL_TEXTURE0 + shadowSampler); - glBindTexture(GL_TEXTURE_2D, 0); - glBindSampler(shadowSampler, 0); - } - - glActiveTexture(GL_TEXTURE0); -} - -void -GlfSimpleLightingContext::SetStateFromOpenGL() -{ - // import classic GL light's parameters into shaded lights - SetUseLighting(glIsEnabled(GL_LIGHTING) == GL_TRUE); - - GfMatrix4d worldToViewMatrix; - glGetDoublev(GL_MODELVIEW_MATRIX, worldToViewMatrix.GetArray()); - GfMatrix4d viewToWorldMatrix = worldToViewMatrix.GetInverse(); - - GLint nLights = 0; - glGetIntegerv(GL_MAX_LIGHTS, &nLights); - - GlfSimpleLightVector lights; - lights.reserve(nLights); - - GlfSimpleLight light; - for(int i = 0; i < nLights; ++i) - { - int lightName = GL_LIGHT0 + i; - if (glIsEnabled(lightName)) { - GLfloat position[4], color[4]; - - glGetLightfv(lightName, GL_POSITION, position); - light.SetPosition(GfVec4f(position)*viewToWorldMatrix); - - glGetLightfv(lightName, GL_AMBIENT, color); - light.SetAmbient(GfVec4f(color)); - - glGetLightfv(lightName, GL_DIFFUSE, color); - light.SetDiffuse(GfVec4f(color)); - - glGetLightfv(lightName, GL_SPECULAR, color); - light.SetSpecular(GfVec4f(color)); - - GLfloat spotDirection[3]; - glGetLightfv(lightName, GL_SPOT_DIRECTION, spotDirection); - light.SetSpotDirection( - viewToWorldMatrix.TransformDir(GfVec3f(spotDirection))); - - GLfloat floatValue; - - glGetLightfv(lightName, GL_SPOT_CUTOFF, &floatValue); - light.SetSpotCutoff(floatValue); - - glGetLightfv(lightName, GL_SPOT_EXPONENT, &floatValue); - light.SetSpotFalloff(floatValue); - - GfVec3f attenuation; - glGetLightfv(lightName, GL_CONSTANT_ATTENUATION, &floatValue); - attenuation[0] = floatValue; - - glGetLightfv(lightName, GL_LINEAR_ATTENUATION, &floatValue); - attenuation[1] = floatValue; - - glGetLightfv(lightName, GL_QUADRATIC_ATTENUATION, &floatValue); - attenuation[2] = floatValue; - - light.SetAttenuation(attenuation); - - lights.push_back(light); - } - } - - SetLights(lights); - - GlfSimpleMaterial material; - - GLfloat color[4], shininess; - glGetMaterialfv(GL_FRONT, GL_AMBIENT, color); - material.SetAmbient(GfVec4f(color)); - glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); - material.SetDiffuse(GfVec4f(color)); - glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); - material.SetSpecular(GfVec4f(color)); - glGetMaterialfv(GL_FRONT, GL_EMISSION, color); - material.SetEmission(GfVec4f(color)); - glGetMaterialfv(GL_FRONT, GL_SHININESS, &shininess); - // clamp to 0.0001, since pow(0,0) is undefined in GLSL. - shininess = std::max(0.0001f, shininess); - material.SetShininess(shininess); - - SetMaterial(material); - - GfVec4f sceneAmbient; - glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &sceneAmbient[0]); - SetSceneAmbient(sceneAmbient); -} - -class GlfSimpleLightingContext::_PostSurfaceShaderState { -public: - _PostSurfaceShaderState(size_t hash, GlfSimpleLightVector const & lights) - : _hash(hash) - { - _Init(lights); - } - - std::string const & GetShaderSource() const { - return _shaderSource; - } - - GlfUniformBlockRefPtr const & GetUniformBlock() const { - return _uniformBlock; - } - - size_t GetHash() const { - return _hash; - } - -private: - void _Init(GlfSimpleLightVector const & lights); - - std::string _shaderSource;; - GlfUniformBlockRefPtr _uniformBlock; - size_t _hash; -}; - -void -GlfSimpleLightingContext::_PostSurfaceShaderState::_Init( - GlfSimpleLightVector const & lights) -{ - TRACE_FUNCTION(); - - // Generate shader code and aggregate uniform block data - - // - // layout(std140) uniform PostSurfaceShaderParams { - // MurkPostParams light1; - // CausticsParams light2; - // ... - // } postSurface; - // - // MAT4 GetWorldToViewInverseMatrix(); - // vec4 postSurfaceShader(vec4 Peye, vec3 Neye, vec4 color) - // { - // vec4 Pworld = vec4(GetWorldToViewInverseMatrix() * Peye); - // color = ApplyMurkPostWorldSpace(postSurface.light1,color,Pworld.xyz); - // color = ApplyCausticsWorldSpace(postSurface.light2,color,Pworld.xyz); - // ... - // return color - // } - // - std::stringstream lightsSourceStr; - std::stringstream paramsSourceStr; - std::stringstream applySourceStr; - - std::vector uniformData; - - std::set activeShaderIdentifiers; - size_t activeShaders = 0; - for (GlfSimpleLight const & light: lights) { - - TfToken const & shaderIdentifier = light.GetPostSurfaceIdentifier(); - std::string const & shaderSource = light.GetPostSurfaceShaderSource(); - VtUCharArray const & shaderParams = light.GetPostSurfaceShaderParams(); - - if (shaderIdentifier.IsEmpty() || - shaderSource.empty() || - shaderParams.empty()) { - continue; - } - - // omit lights with misaligned parameter data - // GLSL std140 packing has a base alignment of "vec4" - size_t const std140Alignment = 4*sizeof(float); - if ((shaderParams.size() % std140Alignment) != 0) { - TF_CODING_ERROR("Invalid shader params size (%zd bytes) " - "for %s (must be a multiple of %zd)\n", - shaderParams.size(), - light.GetID().GetText(), - std140Alignment); - continue; - } - - TF_DEBUG(GLF_DEBUG_POST_SURFACE_LIGHTING).Msg( - "PostSurfaceLight: %s: %s\n", - shaderIdentifier.GetText(), - light.GetID().GetText()); - - ++activeShaders; - - // emit per-light type shader source only one time - if (!activeShaderIdentifiers.count(shaderIdentifier)) { - activeShaderIdentifiers.insert(shaderIdentifier); - lightsSourceStr << shaderSource; - } - - // add a per-light parameter declaration to the uniform block - paramsSourceStr << " " - << shaderIdentifier << "Params " - << "light"<Update(uniformData.data(), uniformData.size()); -} - -static size_t -_ComputeHash(GlfSimpleLightVector const & lights) -{ - TRACE_FUNCTION(); - - // hash includes light type and shader source but not parameter values - size_t hash = 0; - for (GlfSimpleLight const & light: lights) { - TfToken const & identifier = light.GetPostSurfaceIdentifier(); - std::string const & shaderSource = light.GetPostSurfaceShaderSource(); - - hash = ArchHash64(identifier.GetText(), identifier.size(), hash); - hash = ArchHash64(shaderSource.c_str(), shaderSource.size(), hash); - } - - return hash; -} - -void -GlfSimpleLightingContext::_ComputePostSurfaceShaderState() -{ - size_t hash = _ComputeHash(GetLights()); - if (!_postSurfaceShaderState || - (_postSurfaceShaderState->GetHash() != hash)) { - _postSurfaceShaderState.reset( - new _PostSurfaceShaderState(hash, GetLights())); - } - _postSurfaceShaderStateValid = true; -} - -size_t -GlfSimpleLightingContext::ComputeShaderSourceHash() -{ - if (!_postSurfaceShaderStateValid) { - _ComputePostSurfaceShaderState(); - } - - if (_postSurfaceShaderState) { - return _postSurfaceShaderState->GetHash(); - } - - return 0; -} - -std::string const & -GlfSimpleLightingContext::ComputeShaderSource(TfToken const &shaderStageKey) -{ - if (!_postSurfaceShaderStateValid) { - _ComputePostSurfaceShaderState(); - } - - if (_postSurfaceShaderState && - shaderStageKey==HioGlslfxTokens->fragmentShader) { - return _postSurfaceShaderState->GetShaderSource(); - } - - static const std::string empty; - return empty; -} - -void -GlfSimpleLightingContext::_BindPostSurfaceShaderParams( - GlfBindingMapPtr const &bindingMap) -{ - if (!_postSurfaceShaderStateValid) { - _ComputePostSurfaceShaderState(); - } - - if (_postSurfaceShaderState && _postSurfaceShaderState->GetUniformBlock()) { - _postSurfaceShaderState->GetUniformBlock()-> - Bind(bindingMap, _tokens->postSurfaceShaderUB); - } -} - - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/simpleShadowArray.cpp b/Sources/OpenUSD/imaging/glf/simpleShadowArray.cpp deleted file mode 100644 index 14e7d9221a..0000000000 --- a/Sources/OpenUSD/imaging/glf/simpleShadowArray.cpp +++ /dev/null @@ -1,450 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -/// \file simpleShadowArray.cpp - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/simpleShadowArray.h" -#include "pxr/imaging/glf/debugCodes.h" -#include "pxr/imaging/glf/diagnostic.h" -#include "pxr/imaging/glf/glContext.h" -#include "pxr/imaging/hio/image.h" - -#include "pxr/base/arch/fileSystem.h" -#include "pxr/base/gf/vec2i.h" -#include "pxr/base/gf/vec4d.h" -#include "pxr/base/tf/debug.h" -#include "pxr/base/tf/envSetting.h" -#include "pxr/base/tf/stringUtils.h" - -#include -#include - - -PXR_NAMESPACE_OPEN_SCOPE - -GlfSimpleShadowArray::GlfSimpleShadowArray() : - _framebuffer(0), - _shadowDepthSampler(0), - _shadowCompareSampler(0), - _unbindRestoreDrawFramebuffer(0), - _unbindRestoreReadFramebuffer(0), - _unbindRestoreViewport{0,0,0,0}, - _texturesAllocatedExternally(false) -{ -} - -GlfSimpleShadowArray::~GlfSimpleShadowArray() -{ - _FreeResources(); -} - -GLuint -GlfSimpleShadowArray::GetShadowMapTexture(int shadowIndex) const -{ - return _textures[shadowIndex]; -} -GLuint -GlfSimpleShadowArray::GetShadowMapDepthSampler() const -{ - if (!_shadowDepthSampler) { - TF_CODING_ERROR("Shadow depth sampler has not been allocated"); - } - return _shadowDepthSampler; -} - -GLuint -GlfSimpleShadowArray::GetShadowMapCompareSampler() const -{ - if (!_shadowCompareSampler) { - TF_CODING_ERROR("Shadow compare sampler has not been allocated"); - } - return _shadowCompareSampler; -} - -void -GlfSimpleShadowArray::SetShadowMapResolutions( - std::vector const& resolutions) -{ - if (_resolutions == resolutions) { - return; - } - - _resolutions = resolutions; - - if (!_texturesAllocatedExternally) { - _FreeTextures(); - } - - size_t numShadowMaps = _resolutions.size(); - if (_viewMatrix.size() != numShadowMaps || - _projectionMatrix.size() != numShadowMaps) { - _viewMatrix.resize(numShadowMaps, GfMatrix4d().SetIdentity()); - _projectionMatrix.resize(numShadowMaps, GfMatrix4d().SetIdentity()); - } - - _texturesAllocatedExternally = false; -} - -size_t -GlfSimpleShadowArray::GetNumShadowMapPasses() const -{ - // we require one pass per shadow map. - return _resolutions.size(); -} - -GfVec2i -GlfSimpleShadowArray::GetShadowMapSize(size_t index) const -{ - GfVec2i shadowMapSize(0); - if (TF_VERIFY(index < _resolutions.size())) { - shadowMapSize = _resolutions[index]; - } - - return shadowMapSize; -} - -GfMatrix4d -GlfSimpleShadowArray::GetViewMatrix(size_t index) const -{ - if (!TF_VERIFY(index < _viewMatrix.size())) { - return GfMatrix4d(1.0); - } - - return _viewMatrix[index]; -} - -void -GlfSimpleShadowArray::SetViewMatrix(size_t index, GfMatrix4d const & matrix) -{ - if (!TF_VERIFY(index < _viewMatrix.size())) { - return; - } - - _viewMatrix[index] = matrix; -} - -GfMatrix4d -GlfSimpleShadowArray::GetProjectionMatrix(size_t index) const -{ - if (!TF_VERIFY(index < _projectionMatrix.size())) { - return GfMatrix4d(1.0); - } - - return _projectionMatrix[index]; -} - -void -GlfSimpleShadowArray::SetProjectionMatrix(size_t index, GfMatrix4d const & matrix) -{ - if (!TF_VERIFY(index < _projectionMatrix.size())) { - return; - } - - _projectionMatrix[index] = matrix; -} - -GfMatrix4d -GlfSimpleShadowArray::GetWorldToShadowMatrix(size_t index) const -{ - GfMatrix4d size = GfMatrix4d().SetScale(GfVec3d(0.5, 0.5, 0.5)); - GfMatrix4d center = GfMatrix4d().SetTranslate(GfVec3d(0.5, 0.5, 0.5)); - return GetViewMatrix(index) * GetProjectionMatrix(index) * size * center; -} - -void -GlfSimpleShadowArray::BeginCapture(size_t index, bool clear) -{ - _BindFramebuffer(index); - - if (clear) { - glClear(GL_DEPTH_BUFFER_BIT); - } - - // save the current viewport - glGetIntegerv(GL_VIEWPORT, _unbindRestoreViewport); - - GfVec2i resolution = GetShadowMapSize(index); - glViewport(0, 0, resolution[0], resolution[1]); - - // depth 1.0 means infinity (no occluders). - // This value is also used as a border color - glDepthRange(0, 0.99999); - glEnable(GL_DEPTH_CLAMP); - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfSimpleShadowArray::EndCapture(size_t index) -{ - // reset to GL default, except viewport - glDepthRange(0, 1.0); - glDisable(GL_DEPTH_CLAMP); - - if (TfDebug::IsEnabled(GLF_DEBUG_DUMP_SHADOW_TEXTURES)) { - HioImage::StorageSpec storage; - GfVec2i resolution = GetShadowMapSize(index); - storage.width = resolution[0]; - storage.height = resolution[1]; - storage.format = HioFormatFloat32; - - // In OpenGL, (0, 0) is the lower left corner. - storage.flipped = true; - - const int numPixels = storage.width * storage.height; - std::vector pixelData(static_cast(numPixels)); - storage.data = static_cast(pixelData.data()); - - glReadPixels(0, - 0, - storage.width, - storage.height, - GL_DEPTH_COMPONENT, - GL_FLOAT, - storage.data); - - GLfloat minValue = std::numeric_limits::max(); - GLfloat maxValue = -std::numeric_limits::max(); - for (int i = 0; i < numPixels; ++i) { - const GLfloat pixelValue = pixelData[i]; - if (pixelValue < minValue) { - minValue = pixelValue; - } - if (pixelValue > maxValue) { - maxValue = pixelValue; - } - } - - // Remap the pixel data so that the furthest depth sample is white and - // the nearest depth sample is black. - for (int i = 0; i < numPixels; ++i) { - pixelData[i] = (pixelData[i] - minValue) / (maxValue - minValue); - } - - const std::string outputImageFile = ArchNormPath( - TfStringPrintf("%s/GlfSimpleShadowArray.index_%zu.tif", - ArchGetTmpDir(), - index)); - HioImageSharedPtr image = HioImage::OpenForWriting(outputImageFile); - if (image->Write(storage)) { - TfDebug::Helper().Msg( - "Wrote shadow texture: %s\n", outputImageFile.c_str()); - } else { - TfDebug::Helper().Msg( - "Failed to write shadow texture: %s\n", outputImageFile.c_str() - ); - } - } - - _UnbindFramebuffer(); - - // restore viewport - glViewport(_unbindRestoreViewport[0], - _unbindRestoreViewport[1], - _unbindRestoreViewport[2], - _unbindRestoreViewport[3]); - - GLF_POST_PENDING_GL_ERRORS(); -} - -// --------- private helpers ---------- -bool -GlfSimpleShadowArray::_ShadowMapExists() const -{ - return !_textures.empty(); -} - -void -GlfSimpleShadowArray::AllocSamplers() -{ - // Samplers - GLfloat border[] = {1, 1, 1, 1}; - - if (!_shadowDepthSampler) { - glGenSamplers(1, &_shadowDepthSampler); - glSamplerParameteri( - _shadowDepthSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri( - _shadowDepthSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri( - _shadowDepthSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glSamplerParameteri( - _shadowDepthSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glSamplerParameterfv( - _shadowDepthSampler, GL_TEXTURE_BORDER_COLOR, border); - } - - if (!_shadowCompareSampler) { - glGenSamplers(1, &_shadowCompareSampler); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glSamplerParameterfv( - _shadowCompareSampler, GL_TEXTURE_BORDER_COLOR, border); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_COMPARE_MODE, - GL_COMPARE_REF_TO_TEXTURE); - glSamplerParameteri( - _shadowCompareSampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL ); - } -} - -void -GlfSimpleShadowArray::_AllocResources() -{ - // Samplers - AllocSamplers(); - - // Shadow maps - if (!_texturesAllocatedExternally) { - _AllocTextures(); - } - - // Framebuffer - if (!_framebuffer) { - glGenFramebuffers(1, &_framebuffer); - } -} - -void -GlfSimpleShadowArray::SetTextures(std::vector textureIds) -{ - _textures = textureIds; - _texturesAllocatedExternally = !textureIds.empty(); -} - -void -GlfSimpleShadowArray::_AllocTextures() -{ - if (!TF_VERIFY(_shadowDepthSampler) || - !TF_VERIFY(_shadowCompareSampler) || - !TF_VERIFY(_textures.empty())) { - TF_CODING_ERROR("Unexpected entry state in %s\n", - TF_FUNC_NAME().c_str()); - return; - } - - GlfSharedGLContextScopeHolder sharedContextScopeHolder; - - // XXX: Currently, we allocate/reallocate ALL shadow maps each time. - for (GfVec2i const& size : _resolutions) { - GLuint id; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, - size[0], size[1], 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); - _textures.push_back(id); - - TF_DEBUG(GLF_DEBUG_SHADOW_TEXTURES).Msg( - "Created shadow map texture of size %dx%d " - "(id %#x)\n" , size[0], size[1], id); - } - - glBindTexture(GL_TEXTURE_2D, 0); - _texturesAllocatedExternally = false; -} - -void -GlfSimpleShadowArray::_FreeResources() -{ - GlfSharedGLContextScopeHolder sharedContextScopeHolder; - - if (!_texturesAllocatedExternally) { - _FreeTextures(); - } - - if (_framebuffer) { - glDeleteFramebuffers(1, &_framebuffer); - _framebuffer = 0; - } - if (_shadowDepthSampler) { - glDeleteSamplers(1, &_shadowDepthSampler); - _shadowDepthSampler = 0; - } - if (_shadowCompareSampler) { - glDeleteSamplers(1, &_shadowCompareSampler); - _shadowCompareSampler = 0; - } -} - -void -GlfSimpleShadowArray::_FreeTextures() -{ - if (!_textures.empty()) { - GlfSharedGLContextScopeHolder sharedContextScopeHolder; - // XXX: Ideally, we don't deallocate all textures, and only those that - // have resolution modified. - - for (GLuint const& id : _textures) { - if (id) { - glDeleteTextures(1, &id); - } - } - _textures.clear(); - - GLF_POST_PENDING_GL_ERRORS(); - } -} - -void -GlfSimpleShadowArray::_BindFramebuffer(size_t index) -{ - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, - (GLint*)&_unbindRestoreDrawFramebuffer); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, - (GLint*)&_unbindRestoreReadFramebuffer); - - if (!_framebuffer || !_ShadowMapExists()) { - _AllocResources(); - } - - glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); - - if (index < _textures.size()) { - glFramebufferTexture(GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, _textures[index], 0); - } else { - TF_CODING_WARNING("Texture index is out of bounds"); - } - - GLF_POST_PENDING_GL_ERRORS(); -} - -void -GlfSimpleShadowArray::_UnbindFramebuffer() -{ - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _unbindRestoreDrawFramebuffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, _unbindRestoreReadFramebuffer); - - GLF_POST_PENDING_GL_ERRORS(); -} - - -PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/OpenUSD/imaging/glf/testGLContext.cpp b/Sources/OpenUSD/imaging/glf/testGLContext.cpp deleted file mode 100644 index 0ddda43592..0000000000 --- a/Sources/OpenUSD/imaging/glf/testGLContext.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#include "pxr/imaging/glf/testGLContext.h" - -#include "pxr/base/tf/diagnostic.h" - -#include - -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -class Glf_TestGLContextPrivate { -public: - Glf_TestGLContextPrivate( Glf_TestGLContextPrivate const * other=NULL ); - - void makeCurrent( ) const; - - bool isValid(); - - bool operator==(const Glf_TestGLContextPrivate& rhs) const - { - return _dpy == rhs._dpy && _context == rhs._context; - } - - static const Glf_TestGLContextPrivate * currentContext(); - - static bool areSharing( const Glf_TestGLContextPrivate * context1, - const Glf_TestGLContextPrivate * context2 ); - -private: - Display * _dpy; - - GLXContext _context; - - Glf_TestGLContextPrivate const * _sharedContext; - - static GLXWindow _win; - - static Glf_TestGLContextPrivate const * _currenGLContext; -}; - -Glf_TestGLContextPrivate const * Glf_TestGLContextPrivate::_currenGLContext=NULL; -GLXWindow Glf_TestGLContextPrivate::_win=0; - -Glf_TestGLContextPrivate::Glf_TestGLContextPrivate( Glf_TestGLContextPrivate const * other ) - : _dpy(NULL), _context(NULL) -{ - static int attribs[] = { GLX_DOUBLEBUFFER, GLX_RGBA_BIT, - GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, - GLX_SAMPLE_BUFFERS, 1, GLX_SAMPLES, 4, None }; - - _dpy = XOpenDisplay(0); - - int n; - GLXFBConfig * fbConfigs = glXChooseFBConfig( _dpy, - DefaultScreen(_dpy), attribs, &n ); - - GLXContext share = other ? other->_context : 0; - - _context = glXCreateNewContext( _dpy, - fbConfigs[0], GLX_RGBA_TYPE, share, true); - - _sharedContext=other ? other : this; - - if (!_win) { - XVisualInfo * vi = glXGetVisualFromFBConfig( _dpy, fbConfigs[0] ); - - XSetWindowAttributes swa; - swa.colormap = XCreateColormap(_dpy, RootWindow(_dpy, vi->screen), - vi->visual, AllocNone); - swa.border_pixel = 0; - swa.event_mask = StructureNotifyMask; - - Window xwin = XCreateWindow( _dpy, RootWindow(_dpy, vi->screen), - 0, 0, 256, 256, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel|CWColormap|CWEventMask, &swa ); - - _win = glXCreateWindow( _dpy, fbConfigs[0], xwin, NULL ); - } -} - -void -Glf_TestGLContextPrivate::makeCurrent( ) const -{ - glXMakeContextCurrent(_dpy, _win, _win, _context); - - _currenGLContext=this; -} - -bool -Glf_TestGLContextPrivate::isValid() -{ - return _context!=NULL; -} - -const Glf_TestGLContextPrivate * -Glf_TestGLContextPrivate::currentContext() -{ - return _currenGLContext; -} - -bool -Glf_TestGLContextPrivate::areSharing( const Glf_TestGLContextPrivate * context1, const Glf_TestGLContextPrivate * context2 ) -{ - if (!context1 || !context2) - return false; - - return context1->_sharedContext==context2->_sharedContext; -} - -Glf_TestGLContextPrivate * -_GetSharedContext() -{ - static Glf_TestGLContextPrivate* sharedCtx = new Glf_TestGLContextPrivate(); - return sharedCtx; -} - -// -// GlfTestGLContextRegistrationInterface -// - -class GlfTestGLContextRegistrationInterface : - public GlfGLContextRegistrationInterface { -public: - GlfTestGLContextRegistrationInterface(); - virtual ~GlfTestGLContextRegistrationInterface(); - - // GlfGLContextRegistrationInterface overrides - virtual GlfGLContextSharedPtr GetShared(); - virtual GlfGLContextSharedPtr GetCurrent(); -}; - -GlfTestGLContextRegistrationInterface::GlfTestGLContextRegistrationInterface() -{ - // Do nothing -} - -GlfTestGLContextRegistrationInterface::~GlfTestGLContextRegistrationInterface() -{ - // Do nothing -} - -GlfGLContextSharedPtr -GlfTestGLContextRegistrationInterface::GetShared() -{ - return GlfGLContextSharedPtr(new GlfTestGLContext(_GetSharedContext())); -} - -GlfGLContextSharedPtr -GlfTestGLContextRegistrationInterface::GetCurrent() -{ - if (const Glf_TestGLContextPrivate* context = - Glf_TestGLContextPrivate::currentContext()) { - return GlfGLContextSharedPtr(new GlfTestGLContext(context)); - } - return GlfGLContextSharedPtr(); -} - -// -// GlfTestGLContext -// - -GlfTestGLContextSharedPtr -GlfTestGLContext::Create( GlfTestGLContextSharedPtr const & share ) -{ - Glf_TestGLContextPrivate * ctx = new Glf_TestGLContextPrivate( - share && share->_context ? share->_context : NULL ); - return GlfTestGLContextSharedPtr( new GlfTestGLContext( ctx ) ); -} - -void -GlfTestGLContext::RegisterGLContextCallbacks() -{ - new GlfTestGLContextRegistrationInterface; -} - -GlfTestGLContext::GlfTestGLContext(Glf_TestGLContextPrivate const * context) : - _context(const_cast(context)) -{ -} - -bool -GlfTestGLContext::IsValid() const -{ - return (_context && _context->isValid()); -} - -void -GlfTestGLContext::_MakeCurrent() -{ - _context->makeCurrent(); -} - -bool -GlfTestGLContext::_IsSharing(GlfGLContextSharedPtr const & otherContext)const -{ -#ifdef MENV30 - GlfTestGLContextSharedPtr otherGlfTestGLContext = - std::dynamic_pointer_cast(otherContext); - return (otherGlfTestGLContext && - Glf_TestGLContextPrivate::areSharing(_context, otherGlfTestGLContext->_context)); -#else - TF_CODING_ERROR("Glf_TestGLContextPrivate::areSharing() is not supported outside of Presto."); - return false; -#endif -} - -bool -GlfTestGLContext::_IsEqual(GlfGLContextSharedPtr const &rhs) const -{ - if (const GlfTestGLContext* rhsRaw = - dynamic_cast(rhs.get())) { - return *_context == *rhsRaw->_context; - } - return false; -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/uniformBlock.cpp b/Sources/OpenUSD/imaging/glf/uniformBlock.cpp deleted file mode 100644 index 7f8e9f73dd..0000000000 --- a/Sources/OpenUSD/imaging/glf/uniformBlock.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -// uniformBlock.cpp -// - -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/imaging/glf/diagnostic.h" -#include "pxr/imaging/glf/uniformBlock.h" -#include "pxr/imaging/glf/bindingMap.h" -#include "pxr/imaging/glf/glContext.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -GlfUniformBlock::GlfUniformBlock(char const *label) : - _buffer(0), _size(0) -{ - glGenBuffers(1, &_buffer); - if (label) { - // Using 'glObjectLabel' is only guaranteed to work on GL resources that - // have been created. glGenBuffers only reserves an id. - // Postpone setting up the debug label until buffer binding. - _debugLabel = label; - } -} - -GlfUniformBlock::~GlfUniformBlock() -{ - GlfSharedGLContextScopeHolder sharedGLContextScopeHolder; - - if (glIsBuffer(_buffer) == GL_TRUE) { - glDeleteBuffers(1, &_buffer); - } -} - -GlfUniformBlockRefPtr -GlfUniformBlock::New(char const *label) -{ - return TfCreateRefPtr(new GlfUniformBlock(label)); -} - -void -GlfUniformBlock::Bind(GlfBindingMapPtr const & bindingMap, - std::string const & identifier) -{ - if (!bindingMap) return; - int binding = bindingMap->GetUniformBinding(identifier); - - glBindBufferBase(GL_UNIFORM_BUFFER, binding, _buffer); - - // Binding the buffer should ensure it is created so we can assign debug lbl - if (!_debugLabel.empty()) { - GlfDebugLabelBuffer(_buffer, _debugLabel.c_str()); - } -} - -void -GlfUniformBlock::Update(const void *data, int size) -{ - GLF_GROUP_FUNCTION(); - - glBindBuffer(GL_UNIFORM_BUFFER, _buffer); - if (_size != size) { - glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STATIC_DRAW); - _size = size; - } - if (size > 0) { - // Bug 95969 BufferSubData w/ size == 0 should be a noop but - // raises errors on some NVIDIA drivers. - glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data); - } - glBindBuffer(GL_UNIFORM_BUFFER, 0); -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/utils.cpp b/Sources/OpenUSD/imaging/glf/utils.cpp deleted file mode 100644 index 1b1389f6ab..0000000000 --- a/Sources/OpenUSD/imaging/glf/utils.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -// utils.cpp -// - -#include "pxr/imaging/glf/utils.h" - -#include "pxr/base/tf/diagnostic.h" -#include "pxr/base/tf/stringUtils.h" - -PXR_NAMESPACE_OPEN_SCOPE - -int -GlfGetNumElements(GLenum format) -{ - switch (format) { - case GL_DEPTH_COMPONENT: - case GL_COLOR_INDEX: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_RED: - return 1; - case GL_LUMINANCE_ALPHA : - case GL_RG: - return 2; - case GL_RGB: - return 3; - case GL_RGBA: - return 4; - default: - TF_CODING_ERROR("Unsupported format"); - return 1; - } -} - -int -GlfGetElementSize(GLenum type) -{ - switch (type) { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - return sizeof(GLubyte); - case GL_UNSIGNED_SHORT: - case GL_SHORT: - return sizeof(GLshort); - case GL_FLOAT: - return sizeof(GLfloat); - case GL_DOUBLE: - return sizeof(GLdouble); - case GL_HALF_FLOAT: - return sizeof(GLhalf); - default: - TF_CODING_ERROR("Unsupported type"); - return sizeof(GLfloat); - } -} - -HioFormat -GlfGetHioFormat(GLenum glFormat, GLenum glType, bool isSRGB) -{ - switch (glFormat){ - case GL_DEPTH_COMPONENT: - case GL_COLOR_INDEX: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_RED: - switch (glType) { - case GL_UNSIGNED_BYTE: - if (isSRGB) { - return HioFormatUNorm8srgb; - } - return HioFormatUNorm8; - case GL_BYTE: - return HioFormatSNorm8; - case GL_UNSIGNED_SHORT: - return HioFormatUInt16; - case GL_SHORT: - return HioFormatInt16; - case GL_UNSIGNED_INT: - return HioFormatUInt32; - case GL_INT: - return HioFormatInt32; - case GL_HALF_FLOAT: - return HioFormatFloat16; - case GL_FLOAT: - return HioFormatFloat32; - case GL_DOUBLE: - return HioFormatDouble64; - } - case GL_LUMINANCE_ALPHA : - case GL_RG: - switch (glType) { - case GL_UNSIGNED_BYTE: - if (isSRGB) { - return HioFormatUNorm8Vec2srgb; - } - return HioFormatUNorm8Vec2; - case GL_BYTE: - return HioFormatSNorm8Vec2; - case GL_UNSIGNED_SHORT: - return HioFormatUInt16Vec2; - case GL_SHORT: - return HioFormatInt16Vec2; - case GL_UNSIGNED_INT: - return HioFormatUInt32Vec2; - case GL_INT: - return HioFormatInt32Vec2; - case GL_HALF_FLOAT: - return HioFormatFloat16Vec2; - case GL_FLOAT: - return HioFormatFloat32Vec2; - case GL_DOUBLE: - return HioFormatDouble64Vec2; - } - case GL_RGB: - switch (glType) { - case GL_UNSIGNED_BYTE: - if (isSRGB) { - return HioFormatUNorm8Vec3srgb; - } - return HioFormatUNorm8Vec3; - case GL_BYTE: - return HioFormatSNorm8Vec3; - case GL_UNSIGNED_SHORT: - return HioFormatUInt16Vec3; - case GL_SHORT: - return HioFormatInt16Vec3; - case GL_UNSIGNED_INT: - return HioFormatUInt32Vec3; - case GL_INT: - return HioFormatInt32Vec3; - case GL_HALF_FLOAT: - return HioFormatFloat16Vec3; - case GL_FLOAT: - return HioFormatFloat32Vec3; - case GL_DOUBLE: - return HioFormatDouble64Vec3; - } - case GL_RGBA: - switch (glType) { - case GL_UNSIGNED_BYTE: - if (isSRGB) { - return HioFormatUNorm8Vec4srgb; - } - return HioFormatUNorm8Vec4; - case GL_BYTE: - return HioFormatSNorm8Vec4; - case GL_UNSIGNED_SHORT: - return HioFormatUInt16Vec4; - case GL_SHORT: - return HioFormatInt16Vec4; - case GL_UNSIGNED_INT: - return HioFormatUInt32Vec4; - case GL_INT: - return HioFormatInt32Vec4; - case GL_HALF_FLOAT: - return HioFormatFloat16Vec4; - case GL_FLOAT: - return HioFormatFloat32Vec4; - case GL_DOUBLE: - return HioFormatDouble64Vec4; - } - case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: - return HioFormatBC6UFloatVec3; - case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: - return HioFormatBC6FloatVec3; - case GL_COMPRESSED_RGBA_BPTC_UNORM: - return HioFormatBC7UNorm8Vec4; - case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: - return HioFormatBC7UNorm8Vec4srgb; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return HioFormatBC1UNorm8Vec4; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return HioFormatBC3UNorm8Vec4; - default: - TF_CODING_ERROR("Unsupported type"); - return HioFormatUNorm8Vec3; - } -} - -bool -GlfCheckGLFrameBufferStatus(GLuint target, std::string * reason) -{ - GLenum status = glCheckFramebufferStatus(target); - - switch (status) { - case GL_FRAMEBUFFER_COMPLETE: - return true; - case GL_FRAMEBUFFER_UNSUPPORTED: - if (reason) { - *reason = "Framebuffer unsupported"; - } - return false; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - if (reason) { - *reason = "Framebuffer incomplete attachment"; - } - return false; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - if (reason) { - *reason = "Framebuffer incomplete missing attachment"; - } - return false; -#if defined (GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - if (reason) { - *reason = "Framebuffer incomplete dimensions"; - } - return false; -#endif -#if defined (GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - if (reason) { - *reason = "Framebuffer incomplete formats"; - } - return false; -#endif - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - if (reason) { - *reason = "Framebuffer incomplete draw buffer"; - } - return false; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - if (reason) { - *reason = "Framebuffer incomplete read buffer"; - } - return false; - default: - if (reason) { - *reason = TfStringPrintf( - "Framebuffer error 0x%x", (unsigned int)(status)); - } - return false; - } -} - -PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/Sources/OpenUSD/imaging/glf/wrapSimpleLight.cpp b/Sources/OpenUSD/imaging/glf/wrapSimpleLight.cpp deleted file mode 100644 index 376f5db482..0000000000 --- a/Sources/OpenUSD/imaging/glf/wrapSimpleLight.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#include "pxr/imaging/glf/simpleLight.h" - -#include - -using namespace boost::python; - -PXR_NAMESPACE_USING_DIRECTIVE - -void wrapSimpleLight() -{ - typedef GlfSimpleLight This; - - class_ ("SimpleLight", init<>() ) - .add_property("transform", - make_function( - &This::GetTransform, - return_value_policy()), - &This::SetTransform) - .add_property("ambient", - make_function( - &This::GetAmbient, - return_value_policy()), - &This::SetAmbient) - .add_property("diffuse", - make_function( - &This::GetDiffuse, - return_value_policy()), - &This::SetDiffuse) - .add_property("specular", - make_function( - &This::GetSpecular, - return_value_policy()), - &This::SetSpecular) - .add_property("position", - make_function( - &This::GetPosition, - return_value_policy()), - &This::SetPosition) - .add_property("spotDirection", - make_function( - &This::GetSpotDirection, - return_value_policy()), - &This::SetSpotDirection) - .add_property("spotCutoff", - make_function( - &This::GetSpotCutoff, - return_value_policy()), - &This::SetSpotCutoff) - .add_property("spotFalloff", - make_function( - &This::GetSpotFalloff, - return_value_policy()), - &This::SetSpotFalloff) - .add_property("attenuation", - make_function( - &This::GetAttenuation, - return_value_policy()), - &This::SetAttenuation) - .add_property("shadowMatrices", - make_function( - &This::GetShadowMatrices, - return_value_policy()), - &This::SetShadowMatrices) - .add_property("shadowResolution", - make_function( - &This::GetShadowResolution, - return_value_policy()), - &This::SetShadowResolution) - .add_property("shadowBias", - make_function( - &This::GetShadowBias, - return_value_policy()), - &This::SetShadowBias) - .add_property("shadowBlur", - make_function( - &This::GetShadowBlur, - return_value_policy()), - &This::SetShadowBlur) - .add_property("shadowIndexStart", - make_function( - &This::GetShadowIndexStart, - return_value_policy()), - &This::SetShadowIndexStart) - .add_property("shadowIndexEnd", - make_function( - &This::GetShadowIndexEnd, - return_value_policy()), - &This::SetShadowIndexEnd) - .add_property("hasShadow", - make_function( - &This::HasShadow, - return_value_policy()), - &This::SetHasShadow) - .add_property("isCameraSpaceLight", - make_function( - &This::IsCameraSpaceLight, - return_value_policy()), - &This::SetIsCameraSpaceLight) - .add_property("id", - make_function( - &This::GetID, - return_value_policy()), - &This::SetID) - .add_property("isDomeLight", - make_function( - &This::IsDomeLight, - return_value_policy()), - &This::SetIsDomeLight) - ; -} diff --git a/Sources/OpenUSD/imaging/glf/wrapSimpleMaterial.cpp b/Sources/OpenUSD/imaging/glf/wrapSimpleMaterial.cpp deleted file mode 100644 index 3d5b9b4d56..0000000000 --- a/Sources/OpenUSD/imaging/glf/wrapSimpleMaterial.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#include "pxr/imaging/glf/simpleMaterial.h" - -#include - -using namespace boost::python; - -PXR_NAMESPACE_USING_DIRECTIVE - -void wrapSimpleMaterial() -{ - typedef GlfSimpleMaterial This; - - class_ ("SimpleMaterial", init<>()) - .add_property("ambient", - make_function( - &This::GetAmbient, - return_value_policy()), - &This::SetAmbient) - .add_property("diffuse", - make_function( - &This::GetDiffuse, - return_value_policy()), - &This::SetDiffuse) - .add_property("specular", - make_function( - &This::GetSpecular, - return_value_policy()), - &This::SetSpecular) - .add_property("emission", - make_function( - &This::GetEmission, - return_value_policy()), - &This::SetEmission) - .add_property("shininess", - make_function( - &This::GetShininess, - return_value_policy()), - &This::SetShininess) - ; -} diff --git a/Sources/OpenUSD/include/OpenUSD.h b/Sources/OpenUSD/include/OpenUSD.h index 41ca458008..fcd49186fa 100644 --- a/Sources/OpenUSD/include/OpenUSD.h +++ b/Sources/OpenUSD/include/OpenUSD.h @@ -83,27 +83,6 @@ #include #endif // defined(PXR_PRMAN_SUPPORT_ENABLED) -// glf -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - // geomUtil #include #include diff --git a/Sources/OpenUSD/include/imaging/glf/bindingMap.h b/Sources/OpenUSD/include/imaging/glf/bindingMap.h deleted file mode 100644 index 6ffc2d4b77..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/bindingMap.h +++ /dev/null @@ -1,139 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_BINDING_MAP_H -#define PXR_IMAGING_GLF_BINDING_MAP_H - -/// \file glf/bindingMap.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/garch/glApi.h" -#include "pxr/base/tf/refBase.h" -#include "pxr/base/tf/stringUtils.h" -#include "pxr/base/tf/token.h" -#include "pxr/base/tf/weakBase.h" - -#include "pxr/base/tf/hashmap.h" - -PXR_NAMESPACE_OPEN_SCOPE - - -class GlfBindingMap : public TfRefBase, public TfWeakBase { -public: - typedef TfHashMap BindingMap; - - GlfBindingMap() - : _samplerBindingBaseIndex(0) - , _uniformBindingBaseIndex(0) - { } - - GLF_API - int GetSamplerUnit(std::string const &name); - GLF_API - int GetSamplerUnit(TfToken const & name); - - // If GetAttributeIndex is called with an unknown - // attribute token they return -1 - GLF_API - int GetAttributeIndex(std::string const & name); - GLF_API - int GetAttributeIndex(TfToken const & name); - - GLF_API - int GetUniformBinding(std::string const & name); - GLF_API - int GetUniformBinding(TfToken const & name); - - GLF_API - bool HasUniformBinding(std::string const & name) const; - GLF_API - bool HasUniformBinding(TfToken const & name) const; - - int GetNumSamplerBindings() const { - return (int)_samplerBindings.size(); - } - - void ClearAttribBindings() { - _attribBindings.clear(); - } - - /// \name Sampler and UBO Bindings - /// - /// Sampler units and uniform block bindings are reset and will be - /// assigned sequentially starting from the specified baseIndex. - /// This allows other subsystems to claim sampler units and uniform - /// block bindings before additional indices are assigned by this - /// binding map. - /// - /// @{ - - void ResetSamplerBindings(int baseIndex) { - _samplerBindings.clear(); - _samplerBindingBaseIndex = baseIndex; - } - - void ResetUniformBindings(int baseIndex) { - _uniformBindings.clear(); - _uniformBindingBaseIndex = baseIndex; - } - - /// @} - - void AddAttribBinding(TfToken const &name, int location) { - _attribBindings[name] = location; - } - - BindingMap const &GetAttributeBindings() const { - return _attribBindings; - } - - GLF_API - void AssignSamplerUnitsToProgram(GLuint program); - - GLF_API - void AssignUniformBindingsToProgram(GLuint program); - - GLF_API - void AddCustomBindings(GLuint program); - - GLF_API - void Debug() const; - -private: - void _AddActiveAttributeBindings(GLuint program); - void _AddActiveUniformBindings(GLuint program); - void _AddActiveUniformBlockBindings(GLuint program); - - BindingMap _attribBindings; - BindingMap _samplerBindings; - BindingMap _uniformBindings; - - int _samplerBindingBaseIndex; - int _uniformBindingBaseIndex; -}; - - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // PXR_IMAGING_GLF_BINDING_MAP_H diff --git a/Sources/OpenUSD/include/imaging/glf/drawTarget.h b/Sources/OpenUSD/include/imaging/glf/drawTarget.h deleted file mode 100644 index 998451f073..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/drawTarget.h +++ /dev/null @@ -1,305 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_DRAW_TARGET_H -#define PXR_IMAGING_GLF_DRAW_TARGET_H - -/// \file glf/drawTarget.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/glf/texture.h" -#include "pxr/imaging/garch/glApi.h" - -#include "pxr/base/gf/vec2i.h" -#include "pxr/base/gf/matrix4d.h" -#include "pxr/base/tf/declarePtrs.h" -#include "pxr/base/tf/refBase.h" -#include "pxr/base/tf/weakBase.h" - -#include -#include -#include -#include - - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_DECLARE_WEAK_AND_REF_PTRS(GlfDrawTarget); -typedef std::shared_ptr GlfGLContextSharedPtr; - -/// \class GlfDrawTarget -/// -/// A class representing a GL render target with mutliple image attachments. -/// -/// A DrawTarget is essentially a custom render pass into which several -/// arbitrary variables can be output into. These can later be used as -/// texture samplers by GLSL shaders. -/// -/// The DrawTarget maintains a map of named attachments that correspond -/// to GL_TEXTURE_2D mages. By default, DrawTargets also create a depth -/// component that is used both as a depth buffer during the draw pass, -/// and can later be accessed as a regular GL_TEXTURE_2D data. Stencils -/// are also available (by setting the format to GL_DEPTH_STENCIL and -/// the internalFormat to GL_DEPTH24_STENCIL8) -/// -class GlfDrawTarget : public TfRefBase, public TfWeakBase { -public: - typedef GlfDrawTarget This; - -public: - - /// Returns a new instance. - GLF_API - static GlfDrawTargetRefPtr New( GfVec2i const & size, - bool requestMSAA = false ); - - /// Returns a new instance. - /// GL framebuffers cannot be shared across contexts, but texture - /// attachments can. In order to reflect this, GlfDrawTargets hold - /// onto their maps of attachments through a RefPtr that can be shared - /// by multiple GlfDrawTargets, one for each of the active GL contexts - /// (ex. one for each active QT viewer). - /// This constructor creates a new framebuffer, but populates its map of - /// attachments by sharing the RefPtr of the source GlfDrawTarget. - GLF_API - static GlfDrawTargetRefPtr New( GlfDrawTargetPtr const & drawtarget ); - - class Attachment : public GlfTexture { - public: - typedef TfDeclarePtrs::RefPtr AttachmentRefPtr; - - GLF_API - static AttachmentRefPtr New(int glIndex, GLenum format, GLenum type, - GLenum internalFormat, GfVec2i size, - unsigned int numSamples); - - GLF_API - ~Attachment() override; - - /// Returns the GL texture index (can be used as any regular GL texture) - GLuint GetGlTextureName() override; - - /// Returns the GL texture index multisampled of this attachment - GLuint GetGlTextureMSName() const { return _textureNameMS; } - - /// Returns the GL format of the texture (GL_RGB, GL_DEPTH_COMPONENT...) - GLenum GetFormat() const { return _format; } - - /// Returns the GL type of the texture (GL_BYTE, GL_INT, GL_FLOAT...) - GLenum GetType() const { return _type; } - - /// Returns the GL internalFormat of the texture - GLenum GetInternalFormat() const { return _internalFormat; } - - /// Returns the GL attachment point index in the framebuffer. - int GetAttach() const { return _glIndex; } - - /// Resize the attachment recreating the texture - GLF_API - void ResizeTexture(const GfVec2i &size); - - // GlfTexture overrides - GLF_API - BindingVector GetBindings(TfToken const & identifier, - GLuint samplerName) override; - GLF_API - VtDictionary GetTextureInfo(bool forceLoad) override; - - /// Updates the contents signature for the underlying texture - /// to allow downstream consumers to know that the texture image - /// data may have changed. - GLF_API - void TouchContents(); - - private: - Attachment(int glIndex, GLenum format, GLenum type, - GLenum internalFormat, GfVec2i size, - unsigned int numSamples); - - void _GenTexture(); - void _DeleteTexture(); - - GLuint _textureName; - GLuint _textureNameMS; - - GLenum _format, - _type, - _internalFormat; - - int _glIndex; - - GfVec2i _size; - - unsigned int _numSamples; - }; - - typedef TfDeclarePtrs::RefPtr AttachmentRefPtr; - - typedef std::map AttachmentsMap; - - /// Add an attachment to the DrawTarget. - GLF_API - void AddAttachment( std::string const & name, - GLenum format, GLenum type, GLenum internalFormat ); - - /// Removes the named attachment from the DrawTarget. - GLF_API - void DeleteAttachment( std::string const & name ); - - /// Clears all the attachments for this DrawTarget. - GLF_API - void ClearAttachments(); - - /// Copies the list of attachments from DrawTarget. - GLF_API - void CloneAttachments( GlfDrawTargetPtr const & drawtarget ); - - /// Returns the list of Attachments for this DrawTarget. - GLF_API - AttachmentsMap const & GetAttachments() const; - - /// Returns the attachment with a given name or TfNullPtr; - GLF_API - AttachmentRefPtr GetAttachment(std::string const & name); - - /// Write the Attachment buffer to an image file (debugging). - GLF_API - bool WriteToFile(std::string const & name, - std::string const & filename, - GfMatrix4d const & viewMatrix = GfMatrix4d(1), - GfMatrix4d const & projectionMatrix = GfMatrix4d(1)); - - /// Resize the DrawTarget. - GLF_API - void SetSize( GfVec2i ); - - /// Returns the size of the DrawTarget. - GfVec2i const & GetSize() const { return _size; } - - /// Returns if the draw target uses msaa - bool HasMSAA() const { return (_numSamples > 1); } - - /// Returns the framebuffer object Id. - GLF_API - GLuint GetFramebufferId() const; - - /// Returns the id of the framebuffer object with MSAA buffers. - GLF_API - GLuint GetFramebufferMSId() const; - - /// Binds the framebuffer. - GLF_API - void Bind(); - - /// Unbinds the framebuffer. - GLF_API - void Unbind(); - - /// Returns whether the framebuffer is currently bound. - GLF_API - bool IsBound() const; - - /// Resolve the MSAA framebuffer to a regular framebuffer. If there - /// is no MSAA enabled, this function does nothing. - GLF_API - void Resolve(); - - /// Resolve several MSAA framebuffers at once. If any framebuffers don't - /// have MSAA enabled, nothing happens to them. - GLF_API - static void Resolve(const std::vector& drawTargets); - - /// Updates the contents signature for attached textures - /// to allow downstream consumers to know that the texture image - /// data may have changed. - GLF_API - void TouchContents(); - - /// Returns whether the enclosed framebuffer object is complete. - /// If \a reason is non-NULL, and this framebuffer is not valid, - /// sets \a reason to the reason why not. - GLF_API - bool IsValid(std::string * reason = NULL); - -protected: - - /// Weak/Ref-based container for the the map of texture attachments. - /// Multiple GlfDrawTargets can jointly share their attachment textures : - /// this construction allows the use of a RefPtr on the map of attachments. - class AttachmentsContainer : public TfRefBase, public TfWeakBase { - public: - AttachmentsMap attachments; - }; - - GLF_API - GlfDrawTarget( GfVec2i const & size, bool requestMSAA ); - - GLF_API - GlfDrawTarget( GlfDrawTargetPtr const & drawtarget ); - - GLF_API - virtual ~GlfDrawTarget(); - -private: - void _GenFrameBuffer(); - - void _BindAttachment( GlfDrawTarget::AttachmentRefPtr const & a ); - - GLuint _AllocAttachment( GLenum format, GLenum type ); - - AttachmentsMap & _GetAttachments() const; - - void _DeleteAttachments( ); - - void _AllocDepth( ); - - bool _Validate(std::string * reason = NULL); - - void _SaveBindingState(); - - void _RestoreBindingState(); - - void _Resolve(); - - GLuint _framebuffer; - GLuint _framebufferMS; - - GLuint _unbindRestoreReadFB, - _unbindRestoreDrawFB; - - int _bindDepth; - - GfVec2i _size; - - unsigned int _numSamples; - - TfRefPtr _attachmentsPtr; - GlfGLContextSharedPtr _owningContext; -}; - - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // GLF_DRAW_TARGET_H diff --git a/Sources/OpenUSD/include/imaging/glf/pch.h b/Sources/OpenUSD/include/imaging/glf/pch.h deleted file mode 100644 index 757120bfbf..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/pch.h +++ /dev/null @@ -1,213 +0,0 @@ -// -// Copyright 2017 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -// WARNING: THIS FILE IS GENERATED. DO NOT EDIT. -// - -#define TF_MAX_ARITY 7 -#include "pxr/pxr.h" -#include "pxr/base/arch/defines.h" -#if defined(ARCH_OS_DARWIN) -#include -#include -#include -#include -#include -#include -#endif -#if defined(ARCH_OS_LINUX) -#include -#include -#include -#include -#include -#include -#endif -#if defined(ARCH_OS_WINDOWS) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include -#include -#include -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PXR_PYTHON_SUPPORT_ENABLED -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__APPLE__) // Fix breakage caused by Python's pyport.h. -#undef tolower -#undef toupper -#endif -#endif // PXR_PYTHON_SUPPORT_ENABLED -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PXR_PYTHON_SUPPORT_ENABLED -#include "pxr/base/tf/pySafePython.h" -#endif // PXR_PYTHON_SUPPORT_ENABLED diff --git a/Sources/OpenUSD/include/imaging/glf/simpleLight.h b/Sources/OpenUSD/include/imaging/glf/simpleLight.h deleted file mode 100644 index a472b91e28..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/simpleLight.h +++ /dev/null @@ -1,240 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_SIMPLE_LIGHT_H -#define PXR_IMAGING_GLF_SIMPLE_LIGHT_H - -/// \file glf/simpleLight.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/base/gf/matrix4d.h" -#include "pxr/base/gf/vec3f.h" -#include "pxr/base/gf/vec4f.h" -#include "pxr/usd/sdf/path.h" -#include "pxr/usd/sdf/assetPath.h" - -#include "pxr/base/tf/token.h" -#include "pxr/base/vt/array.h" -#include "pxr/base/vt/dictionary.h" - -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -class GlfSimpleLight final { -public: - GLF_API - GlfSimpleLight(GfVec4f const & position = GfVec4f(0.0, 0.0, 0.0, 1.0)); - GLF_API - ~GlfSimpleLight(); - - GLF_API - GfMatrix4d const & GetTransform() const; - GLF_API - void SetTransform(GfMatrix4d const & mat); - - GLF_API - GfVec4f const & GetAmbient() const; - GLF_API - void SetAmbient(GfVec4f const & ambient); - - GLF_API - GfVec4f const & GetDiffuse() const; - GLF_API - void SetDiffuse(GfVec4f const & diffuse); - - GLF_API - GfVec4f const & GetSpecular() const; - GLF_API - void SetSpecular(GfVec4f const & specular); - - GLF_API - GfVec4f const & GetPosition() const; - GLF_API - void SetPosition(GfVec4f const & position); - - GLF_API - GfVec3f const & GetSpotDirection() const; - GLF_API - void SetSpotDirection(GfVec3f const & spotDirection); - - GLF_API - float const & GetSpotCutoff() const; - GLF_API - void SetSpotCutoff(float const & spotCutoff); - - GLF_API - float const & GetSpotFalloff() const; - GLF_API - void SetSpotFalloff(float const & spotFalloff); - - GLF_API - GfVec3f const & GetAttenuation() const; - GLF_API - void SetAttenuation(GfVec3f const & attenuation); - - GLF_API - std::vector const & GetShadowMatrices() const; - GLF_API - void SetShadowMatrices(std::vector const &matrix); - - GLF_API - int GetShadowResolution() const; - GLF_API - void SetShadowResolution(int resolution); - - GLF_API - float GetShadowBias() const; - GLF_API - void SetShadowBias(float bias); - - GLF_API - float GetShadowBlur() const; - GLF_API - void SetShadowBlur(float blur); - - GLF_API - int GetShadowIndexStart() const; - GLF_API - void SetShadowIndexStart(int shadowStart); - - GLF_API - int GetShadowIndexEnd() const; - GLF_API - void SetShadowIndexEnd(int shadowEnd); - - GLF_API - bool HasShadow() const; - GLF_API - void SetHasShadow(bool hasShadow); - - GLF_API - bool HasIntensity() const; - GLF_API - void SetHasIntensity(bool hasIntensity); - - GLF_API - bool IsCameraSpaceLight() const; - GLF_API - - void SetIsCameraSpaceLight(bool isCameraSpaceLight); - GLF_API - SdfPath const & GetID() const; - GLF_API - void SetID(SdfPath const & id); - - GLF_API - bool IsDomeLight() const; - GLF_API - void SetIsDomeLight(bool isDomeLight); - - /// The path to the (unprocessed) environment map texture. - /// - /// All textures actually used by the dome light (irradiance, prefilter, - /// brdf) are derived from this texture in a pre-calculation step. - GLF_API - const SdfAssetPath &GetDomeLightTextureFile() const; - GLF_API - void SetDomeLightTextureFile(const SdfAssetPath &); - - - /// \name Post Surface Lighting - /// - /// Post surface lighting is evaluated after other surface illumination - /// and can be used to implement lighting effects beyond those that - /// correspond to basic positional lighting, e.g. range base fog, etc. - /// - /// @{ - - GLF_API - TfToken const & GetPostSurfaceIdentifier() const; - GLF_API - std::string const & GetPostSurfaceShaderSource() const; - GLF_API - VtUCharArray const & GetPostSurfaceShaderParams() const; - - GLF_API - void SetPostSurfaceParams(TfToken const & identifier, - std::string const & shaderSource, - VtUCharArray const & shaderParams); - - /// @} - - GLF_API - bool operator ==(GlfSimpleLight const &other) const; - GLF_API - bool operator !=(GlfSimpleLight const &other) const; - -private: - GLF_API - friend std::ostream & operator <<(std::ostream &out, - const GlfSimpleLight& v); - GfVec4f _ambient; - GfVec4f _diffuse; - GfVec4f _specular; - GfVec4f _position; - GfVec3f _spotDirection; - float _spotCutoff; - float _spotFalloff; - GfVec3f _attenuation; - bool _isCameraSpaceLight; - bool _hasIntensity; - - bool _hasShadow; - int _shadowResolution; - float _shadowBias; - float _shadowBlur; - int _shadowIndexStart; - int _shadowIndexEnd; - - GfMatrix4d _transform; - std::vector _shadowMatrices; - - // domeLight specific parameters - bool _isDomeLight; - // path to texture for dome light. - SdfAssetPath _domeLightTextureFile; - - TfToken _postSurfaceIdentifier; - std::string _postSurfaceShaderSource; - VtUCharArray _postSurfaceShaderParams; - - SdfPath _id; -}; - -// VtValue requirements -GLF_API -std::ostream& operator<<(std::ostream& out, const GlfSimpleLight& v); - -typedef std::vector GlfSimpleLightVector; - -// VtValue requirements -GLF_API -std::ostream& operator<<(std::ostream& out, const GlfSimpleLightVector& pv); - - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif diff --git a/Sources/OpenUSD/include/imaging/glf/simpleLightingContext.h b/Sources/OpenUSD/include/imaging/glf/simpleLightingContext.h deleted file mode 100644 index a29c412f03..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/simpleLightingContext.h +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_SIMPLE_LIGHTING_CONTEXT_H -#define PXR_IMAGING_GLF_SIMPLE_LIGHTING_CONTEXT_H - -/// \file glf/simpleLightingContext.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/glf/simpleLight.h" -#include "pxr/imaging/glf/simpleMaterial.h" -#include "pxr/imaging/glf/simpleShadowArray.h" - -#include "pxr/base/gf/matrix4d.h" -#include "pxr/base/gf/vec4f.h" - -#include "pxr/base/tf/declarePtrs.h" -#include "pxr/base/tf/refBase.h" -#include "pxr/base/tf/weakBase.h" -#include "pxr/base/tf/token.h" - -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -TF_DECLARE_WEAK_AND_REF_PTRS(GlfBindingMap); -TF_DECLARE_WEAK_AND_REF_PTRS(GlfUniformBlock); -TF_DECLARE_WEAK_AND_REF_PTRS(GlfSimpleLightingContext); -TF_DECLARE_WEAK_AND_REF_PTRS(GlfSimpleShadowArray); - -class GlfSimpleLightingContext : public TfRefBase, public TfWeakBase { -public: - typedef GlfSimpleLightingContext This; - - GLF_API - static GlfSimpleLightingContextRefPtr New(); - - GLF_API - void SetLights(GlfSimpleLightVector const & lights); - GLF_API - GlfSimpleLightVector const & GetLights() const; - - // returns the effective number of lights taken into account - // in composable/compatible shader constraints - GLF_API - int GetNumLightsUsed() const; - - // returns the number of shadow maps needed, by summing shadow maps - // allocated to each light. - GLF_API - int ComputeNumShadowsUsed() const; - - GLF_API - void SetShadows(GlfSimpleShadowArrayRefPtr const & shadows); - GLF_API - GlfSimpleShadowArrayRefPtr const & GetShadows() const; - - GLF_API - void SetMaterial(GlfSimpleMaterial const & material); - GLF_API - GlfSimpleMaterial const & GetMaterial() const; - - GLF_API - void SetSceneAmbient(GfVec4f const & sceneAmbient); - GLF_API - GfVec4f const & GetSceneAmbient() const; - - GLF_API - void SetCamera(GfMatrix4d const &worldToViewMatrix, - GfMatrix4d const &projectionMatrix); - - GLF_API - void SetUseLighting(bool val); - GLF_API - bool GetUseLighting() const; - - // returns true if any light has shadow enabled. - GLF_API - bool GetUseShadows() const; - - GLF_API - void SetUseColorMaterialDiffuse(bool val); - GLF_API - bool GetUseColorMaterialDiffuse() const; - - GLF_API - void InitUniformBlockBindings(GlfBindingMapPtr const &bindingMap) const; - GLF_API - void InitSamplerUnitBindings(GlfBindingMapPtr const &bindingMap) const; - - GLF_API - void BindUniformBlocks(GlfBindingMapPtr const &bindingMap); - GLF_API - void BindSamplers(GlfBindingMapPtr const &bindingMap); - - GLF_API - void UnbindSamplers(GlfBindingMapPtr const &bindingMap); - - GLF_API - void SetStateFromOpenGL(); - - /// \name Post Surface Lighting - /// - /// This context can provide additional shader source, currently - /// used to implement post surface lighting, along with a hash - /// to help de-duplicate use by client shader programs. - /// - /// @{ - - GLF_API - size_t ComputeShaderSourceHash(); - - GLF_API - std::string const & ComputeShaderSource(TfToken const &shaderStageKey); - - /// @} - -protected: - GLF_API - GlfSimpleLightingContext(); - GLF_API - ~GlfSimpleLightingContext(); - - void _ComputePostSurfaceShaderState(); - void _BindPostSurfaceShaderParams(GlfBindingMapPtr const &bindingMap); - -private: - GlfSimpleLightVector _lights; - GlfSimpleShadowArrayRefPtr _shadows; - - GfMatrix4d _worldToViewMatrix; - GfMatrix4d _projectionMatrix; - - GlfSimpleMaterial _material; - GfVec4f _sceneAmbient; - - bool _useLighting; - bool _useShadows; - bool _useColorMaterialDiffuse; - - GlfUniformBlockRefPtr _lightingUniformBlock; - GlfUniformBlockRefPtr _shadowUniformBlock; - GlfUniformBlockRefPtr _materialUniformBlock; - GlfUniformBlockRefPtr _bindlessShadowlUniformBlock; - - class _PostSurfaceShaderState; - std::unique_ptr<_PostSurfaceShaderState> _postSurfaceShaderState; - - bool _lightingUniformBlockValid; - bool _shadowUniformBlockValid; - bool _materialUniformBlockValid; - bool _postSurfaceShaderStateValid; -}; - - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif diff --git a/Sources/OpenUSD/include/imaging/glf/simpleShadowArray.h b/Sources/OpenUSD/include/imaging/glf/simpleShadowArray.h deleted file mode 100644 index f5acc3fd62..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/simpleShadowArray.h +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_SIMPLE_SHADOW_ARRAY_H -#define PXR_IMAGING_GLF_SIMPLE_SHADOW_ARRAY_H - -/// \file glf/simpleShadowArray.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/base/tf/declarePtrs.h" -#include "pxr/base/tf/refPtr.h" -#include "pxr/base/tf/weakPtr.h" -#include "pxr/base/gf/matrix4d.h" -#include "pxr/base/gf/vec2i.h" -#include "pxr/base/gf/vec4d.h" -#include "pxr/imaging/garch/glApi.h" - -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -class GlfSimpleShadowArray : public TfRefBase, - public TfWeakBase -{ -public: - GLF_API - GlfSimpleShadowArray(); - GLF_API - ~GlfSimpleShadowArray() override; - - // Disallow copies - GlfSimpleShadowArray(const GlfSimpleShadowArray&) = delete; - GlfSimpleShadowArray& operator=(const GlfSimpleShadowArray&) = delete; - - // Returns the GL texture id of the shadow texture. - GLF_API - GLuint GetShadowMapTexture(int shadowIndex) const; - - // Returns the GL sampler id of the sampler object used to read the raw - // depth values. - GLF_API - GLuint GetShadowMapDepthSampler() const; - - // Returns the GL sampler id of the sampler object used for depth comparison - GLF_API - GLuint GetShadowMapCompareSampler() const; - - // Set the resolutions of all the shadow maps necessary. The number of - // resolutions corresponds to the number of shadow map textures necessary, - // which is currently one per shadow casting light. - GLF_API - void SetShadowMapResolutions(std::vector const& resolutions); - - // Returns the number of shadow map generation passes required, which is - // currently one per shadow map (corresponding to a shadow casting light). - GLF_API - size_t GetNumShadowMapPasses() const; - - // Returns the shadow map resolution for a given pass. - // this returns the resolution of the corresponding shadow map, - GLF_API - GfVec2i GetShadowMapSize(size_t pass) const; - - // Get/Set the view (world to shadow camera) transform to use for a given - // shadow map generation pass. - GLF_API - GfMatrix4d GetViewMatrix(size_t index) const; - GLF_API - void SetViewMatrix(size_t index, GfMatrix4d const & matrix); - - // Get/Set the projection transform to use for a given shadow map generation - // pass. - GLF_API - GfMatrix4d GetProjectionMatrix(size_t index) const; - GLF_API - void SetProjectionMatrix(size_t index, GfMatrix4d const & matrix); - - GLF_API - GfMatrix4d GetWorldToShadowMatrix(size_t index) const; - - // Bind necessary resources for a given shadow map generation pass. - GLF_API - void BeginCapture(size_t index, bool clear); - - // Unbind necssary resources after a shadow map gneration pass. - GLF_API - void EndCapture(size_t index); - - // Sets the GL texture ids of the shadow textures, as opposed to creating - // them internally with _AllocTextures(). - GLF_API - void SetTextures(std::vector textureIds); - - // Allocates the shadow samplers. - GLF_API - void AllocSamplers(); - -private: - void _AllocResources(); - void _AllocTextures(); - void _FreeResources(); - void _FreeTextures(); - bool _ShadowMapExists() const; - void _BindFramebuffer(size_t index); - void _UnbindFramebuffer(); - -private: - std::vector _resolutions; - std::vector _textures; - - std::vector _viewMatrix; - std::vector _projectionMatrix; - - GLuint _framebuffer; - - GLuint _shadowDepthSampler; - GLuint _shadowCompareSampler; - - GLuint _unbindRestoreDrawFramebuffer; - GLuint _unbindRestoreReadFramebuffer; - - GLint _unbindRestoreViewport[4]; - - bool _texturesAllocatedExternally; -}; - - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif diff --git a/Sources/OpenUSD/include/imaging/glf/texture.h b/Sources/OpenUSD/include/imaging/glf/texture.h deleted file mode 100644 index 6576d115a2..0000000000 --- a/Sources/OpenUSD/include/imaging/glf/texture.h +++ /dev/null @@ -1,176 +0,0 @@ -// -// Copyright 2016 Pixar -// -// Licensed under the Apache License, Version 2.0 (the "Apache License") -// with the following modification; you may not use this file except in -// compliance with the Apache License and the following modification to it: -// Section 6. Trademarks. is deleted and replaced with: -// -// 6. Trademarks. This License does not grant permission to use the trade -// names, trademarks, service marks, or product names of the Licensor -// and its affiliates, except as required to comply with Section 4(c) of -// the License and to reproduce the content of the NOTICE file. -// -// You may obtain a copy of the Apache License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the Apache License with the above modification is -// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the Apache License for the specific -// language governing permissions and limitations under the Apache License. -// -#ifndef PXR_IMAGING_GLF_TEXTURE_H -#define PXR_IMAGING_GLF_TEXTURE_H - -/// \file glf/texture.h - -#include "pxr/pxr.h" -#include "pxr/imaging/glf/api.h" -#include "pxr/imaging/hio/image.h" -#include "pxr/base/tf/declarePtrs.h" -#include "pxr/base/tf/refPtr.h" -#include "pxr/base/tf/staticTokens.h" -#include "pxr/base/tf/weakPtr.h" -#include "pxr/base/vt/dictionary.h" - -#include "pxr/imaging/garch/glApi.h" - -#include -#include -#include - -PXR_NAMESPACE_OPEN_SCOPE - - -#define GLF_TEXTURE_TOKENS \ - (texels) \ - (layout) - -TF_DECLARE_PUBLIC_TOKENS(GlfTextureTokens, GLF_API, GLF_TEXTURE_TOKENS); - -TF_DECLARE_WEAK_AND_REF_PTRS(GlfTexture); - -/// \class GlfTexture -/// -/// Represents a texture object in Glf. -/// -/// A texture is typically defined by reading texture image data from an image -/// file but a texture might also represent an attachment of a draw target. -/// -class GlfTexture : public TfRefBase, public TfWeakBase -{ -public: - /// \class Binding - /// - /// A texture has one or more bindings which describe how the different - /// aspects of the texture should be bound in order to allow shader - /// access. Most textures will have a single binding for the role - /// "texels", but some textures might need multiple bindings, e.g. a - /// ptexTexture will have an additional binding for the role "layout". - /// - struct Binding { - Binding(TfToken name, TfToken role, GLenum target, - GLuint textureId, GLuint samplerId) - : name(name) - , role(role) - , target(target) - , textureId(textureId) - , samplerId(samplerId) { } - - TfToken name; - TfToken role; - GLenum target; - GLuint textureId; - GLuint samplerId; - }; - typedef std::vector BindingVector; - - GLF_API - virtual ~GlfTexture() = 0; - - // Disallow copies - GlfTexture(const GlfTexture&) = delete; - GlfTexture& operator=(const GlfTexture&) = delete; - - /// Returns the bindings to use this texture for the shader resource - /// named \a identifier. If \a samplerId is specified, the bindings - /// returned will use this samplerId for resources which can be sampled. - virtual BindingVector GetBindings(TfToken const & identifier, - GLuint samplerId = 0) = 0; - - /// Returns the OpenGl texture name for the texture. - virtual GLuint GetGlTextureName() = 0; - - /// Amount of memory used to store the texture - GLF_API - size_t GetMemoryUsed() const; - - /// Amount of memory the user wishes to allocate to the texture - GLF_API - size_t GetMemoryRequested() const; - - /// Specify the amount of memory the user wishes to allocate to the texture - GLF_API - void SetMemoryRequested(size_t targetMemory); - - virtual VtDictionary GetTextureInfo(bool forceLoad) = 0; - - GLF_API - virtual bool IsMinFilterSupported(GLenum filter); - - GLF_API - virtual bool IsMagFilterSupported(GLenum filter); - - /// static reporting function - GLF_API - static size_t GetTextureMemoryAllocated(); - - /// Returns an identifier that can be used to determine when the - /// contents of this texture (i.e. its image data) has changed. - /// - /// The contents of most textures will be immutable for the lifetime - /// of the texture. However, the contents of the texture attachments - /// of a draw target change when the draw target is updated. - GLF_API - size_t GetContentsID() const; - - GLF_API - HioImage::ImageOriginLocation GetOriginLocation() const; - - GLF_API - bool IsOriginLowerLeft() const; - -protected: - GLF_API - GlfTexture(); - - GLF_API - GlfTexture(HioImage::ImageOriginLocation originLocation); - - GLF_API - void _SetMemoryUsed(size_t size); - - GLF_API - virtual void _OnMemoryRequestedDirty(); - - GLF_API - void _UpdateContentsID(); - -private: - size_t _memoryUsed; - size_t _memoryRequested; - size_t _contentsID; - HioImage::ImageOriginLocation _originLocation; -}; - -class GlfTextureFactoryBase : public TfType::FactoryBase { -public: - virtual GlfTextureRefPtr New(const TfToken& texturePath, - HioImage::ImageOriginLocation originLocation) const = 0; -}; - -PXR_NAMESPACE_CLOSE_SCOPE - -#endif // PXR_IMAGING_GLF_TEXTURE_H diff --git a/Sources/PixarUSD/Bundle.swift b/Sources/PixarUSD/Bundle.swift index 91b5cd4cdd..08ff6f168c 100644 --- a/Sources/PixarUSD/Bundle.swift +++ b/Sources/PixarUSD/Bundle.swift @@ -180,6 +180,10 @@ public extension Bundle * Where ``Hio`` application bundle resources are located. */ static let hio = Bundle(path: "\(pxrRoot)/SwiftUSD_Hio\(ext)") + /** + * Where ``Glf`` application bundle resources are located. */ + static let glf = Bundle(path: "\(pxrRoot)/SwiftUSD_Glf\(ext)") + /** * Where ``Tf`` python bundle resources are located. */ static let pyTf = Bundle(path: "\(pxrRoot)/SwiftUSD_PyTf\(ext)") @@ -315,6 +319,10 @@ public extension Bundle /** * Where ``Garch`` application bundle resources are located. */ static let pyGarch = Bundle(path: "\(pxrRoot)/SwiftUSD_PyGarch\(ext)") + + /** + * Where ``Glf`` application bundle resources are located. */ + static let pyGlf = Bundle(path: "\(pxrRoot)/SwiftUSD_PyGlf\(ext)") } public enum BundleKind @@ -431,6 +439,7 @@ public enum BundleFramework: CaseIterable case hgiVulkan case hgiGL case hio + case glf public var resourcePath: String? { @@ -462,6 +471,7 @@ public enum BundleFramework: CaseIterable case .hgiVulkan: Bundle.hgiVulkan?.resourcePath case .hgiGL: Bundle.hgiGL?.resourcePath case .hio: Bundle.hio?.resourcePath + case .glf: Bundle.glf?.resourcePath } } } @@ -502,6 +512,7 @@ public enum BundlePython: CaseIterable case pyCameraUtil case pyPxOsd case pyGarch + case pyGlf public var resourcePath: String? { @@ -541,6 +552,7 @@ public enum BundlePython: CaseIterable case .pyCameraUtil: Bundle.pyCameraUtil?.resourcePath case .pyPxOsd: Bundle.pyPxOsd?.resourcePath case .pyGarch: Bundle.pyGarch?.resourcePath + case .pyGlf: Bundle.pyGlf?.resourcePath } } } diff --git a/Sources/PixarUSD/Imaging/Glf/Glf.swift b/Sources/PixarUSD/Imaging/Glf/Glf.swift new file mode 100644 index 0000000000..330c47d3ce --- /dev/null +++ b/Sources/PixarUSD/Imaging/Glf/Glf.swift @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------- + * :: : M E T A V E R S E : :: + * ---------------------------------------------------------------- + * This software is Licensed under the terms of the Apache License, + * version 2.0 (the "Apache License") with the following additional + * modification; you may not use this file except within compliance + * of the Apache License and the following modification made to it. + * Section 6. Trademarks. is deleted and replaced with: + * + * Trademarks. This License does not grant permission to use any of + * its trade names, trademarks, service marks, or the product names + * of this Licensor or its affiliates, except as required to comply + * with Section 4(c.) of this License, and to reproduce the content + * of the NOTICE file. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND without even an + * implied warranty of MERCHANTABILITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the Apache License for more details. + * + * You should have received a copy for this software license of the + * Apache License along with this program; or, if not, please write + * to the Free Software Foundation Inc., with the following address + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 2024 Wabi Foundation. All Rights Reserved. + * ---------------------------------------------------------------- + * . x x x . o o o . x x x . : : : . o x o . : : : . + * ---------------------------------------------------------------- */ + +import Glf + +/** + * # ``Glf`` + * + * **OpenGL Foundations** + * + * ## Overview + * + * Utility classes for OpenGL output. */ +public enum Glf +{}