From d19bfa69f2a9942f9bb6abe1334ff1b2ea0c6b1e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 21 Jan 2015 10:07:10 -0800 Subject: [PATCH] Even more gpu::Texture in the model rnedering --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 246 ++++++++++++++------ libraries/gpu/src/gpu/Texture.cpp | 10 +- libraries/gpu/src/gpu/Texture.h | 61 ++--- libraries/render-utils/src/Model.cpp | 32 ++- libraries/render-utils/src/TextureCache.cpp | 15 +- libraries/render-utils/src/TextureCache.h | 4 +- 6 files changed, 231 insertions(+), 137 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 9582354d57..e23f6fdaec 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -29,84 +29,174 @@ public: GLenum format; GLenum type; - static GLTexelFormat evalGLTexelFormat(const Element& pixel) { - GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}; + static GLTexelFormat evalGLTexelFormat(const Element& dstFormat, const Element& srcFormat) { + if (dstFormat != srcFormat) { + GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}; - switch(pixel.getDimension()) { - case gpu::SCALAR: { - texel.format = GL_RED; - texel.type = _elementTypeToGLType[pixel.getType()]; + switch(dstFormat.getDimension()) { + case gpu::SCALAR: { + texel.format = GL_RED; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RED; + break; + case gpu::DEPTH: + texel.internalFormat = GL_DEPTH_COMPONENT; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; + + case gpu::VEC2: { + texel.format = GL_RG; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RG; + break; + case gpu::DEPTH_STENCIL: + texel.internalFormat = GL_DEPTH_STENCIL; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + + } + break; + + case gpu::VEC3: { + texel.format = GL_RGB; + + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RGB; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; + + case gpu::VEC4: { + texel.format = GL_RGBA; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(srcFormat.getSemantic()) { + case gpu::BGRA: + texel.format = GL_BGRA; + break; + case gpu::RGB: + case gpu::RGBA: + default: + break; + }; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + texel.internalFormat = GL_RGB; + break; + case gpu::RGBA: + texel.internalFormat = GL_RGBA; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; - switch(pixel.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_RED; - break; - case gpu::DEPTH: - texel.internalFormat = GL_DEPTH_COMPONENT; - break; default: qDebug() << "Unknown combination of texel format"; } - } - break; + return texel; + } else { + GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}; - case gpu::VEC2: { - texel.format = GL_RG; - texel.type = _elementTypeToGLType[pixel.getType()]; + switch(dstFormat.getDimension()) { + case gpu::SCALAR: { + texel.format = GL_RED; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RED; + break; + case gpu::DEPTH: + texel.internalFormat = GL_DEPTH_COMPONENT; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; + + case gpu::VEC2: { + texel.format = GL_RG; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RG; + break; + case gpu::DEPTH_STENCIL: + texel.internalFormat = GL_DEPTH_STENCIL; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + + } + break; + + case gpu::VEC3: { + texel.format = GL_RGB; + + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + case gpu::RGBA: + texel.internalFormat = GL_RGB; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; + + case gpu::VEC4: { + texel.format = GL_RGBA; + texel.type = _elementTypeToGLType[dstFormat.getType()]; + + switch(dstFormat.getSemantic()) { + case gpu::RGB: + texel.internalFormat = GL_RGB; + break; + case gpu::RGBA: + texel.internalFormat = GL_RGBA; + break; + default: + qDebug() << "Unknown combination of texel format"; + } + } + break; - switch(pixel.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_RG; - break; - case gpu::DEPTH_STENCIL: - texel.internalFormat = GL_DEPTH_STENCIL; - break; default: qDebug() << "Unknown combination of texel format"; } - + return texel; } - break; - - case gpu::VEC3: { - texel.format = GL_RGB; - - texel.type = _elementTypeToGLType[pixel.getType()]; - - switch(pixel.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_RGB; - break; - default: - qDebug() << "Unknown combination of texel format"; - } - } - break; - - case gpu::VEC4: { - texel.format = GL_RGBA; - texel.type = _elementTypeToGLType[pixel.getType()]; - - switch(pixel.getSemantic()) { - case gpu::RGB: - texel.internalFormat = GL_RGB; - break; - case gpu::RGBA: - texel.internalFormat = GL_RGBA; - break; - default: - qDebug() << "Unknown combination of texel format"; - } - } - break; - - default: - qDebug() << "Unknown combination of texel format"; - } - return texel; } }; @@ -137,16 +227,21 @@ void GLBackend::syncGPUObject(const Texture& texture) { // GO through the process of allocating the correct storage and/or update the content switch (texture.getType()) { case Texture::TEX_2D: { - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat()); if (needUpdate) { - if (texture.isSysmemMipAvailable(0)) { + if (texture.isStoredMipAvailable(0)) { GLint boundTex = -1; glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex); + + Texture::PixelsPointer mip = texture.accessStoredMip(0); + const GLvoid* bytes = mip->_sysmem.read(); + Element srcFormat = mip->_format; + + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); glBindTexture(GL_TEXTURE_2D, object->_texture); glTexSubImage2D(GL_TEXTURE_2D, 0, texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, - texelFormat.format, texelFormat.type, texture.readMip(0)); + texelFormat.format, texelFormat.type, bytes); if (texture.isAutogenerateMips()) { glGenerateMipmap(GL_TEXTURE_2D); @@ -156,14 +251,21 @@ void GLBackend::syncGPUObject(const Texture& texture) { } } else { const GLvoid* bytes = 0; - if (texture.isSysmemMipAvailable(0)) { - bytes = texture.readMip(0); + Element srcFormat = texture.getTexelFormat(); + if (texture.isStoredMipAvailable(0)) { + Texture::PixelsPointer mip = texture.accessStoredMip(0); + + bytes = mip->_sysmem.read(); + srcFormat = mip->_format; + object->_contentStamp = texture.getDataStamp(); } GLint boundTex = -1; glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex); glBindTexture(GL_TEXTURE_2D, object->_texture); + + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); glTexImage2D(GL_TEXTURE_2D, 0, texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index e0391cb43b..5a52529403 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -218,7 +218,7 @@ uint16 Texture::autoGenerateMips(uint16 maxMip) { } uint16 Texture::getStoredMipWidth(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip && mip->_sysmem.getSize()) { return evalMipWidth(level); } else { @@ -227,7 +227,7 @@ uint16 Texture::getStoredMipWidth(uint16 level) const { } uint16 Texture::getStoredMipHeight(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip && mip->_sysmem.getSize()) { return evalMipHeight(level); } else { @@ -236,7 +236,7 @@ uint16 Texture::getStoredMipHeight(uint16 level) const { } uint16 Texture::getStoredMipDepth(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip && mip->_sysmem.getSize()) { return evalMipDepth(level); } else { @@ -245,7 +245,7 @@ uint16 Texture::getStoredMipDepth(uint16 level) const { } uint32 Texture::getStoredMipNumTexels(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip && mip->_sysmem.getSize()) { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } else { @@ -254,7 +254,7 @@ uint32 Texture::getStoredMipNumTexels(uint16 level) const { } uint32 Texture::getStoredMipSize(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip && mip->_sysmem.getSize()) { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); } else { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 8f63abe005..e9a6afe0f2 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -29,7 +29,7 @@ public: Sysmem _sysmem; Element _format; }; - typedef std::shared_ptr PixelsPointer; + typedef QSharedPointer< Pixels > PixelsPointer; enum Type { TEX_1D = 0, @@ -49,7 +49,7 @@ public: const Stamp getStamp() const { return _stamp; } const Stamp getDataStamp(uint16 level = 0) const { - const Pixels* mip = accessStoredMip(level); + PixelsPointer mip = accessStoredMip(level); if (mip) { return mip->_sysmem.getStamp(); } @@ -87,8 +87,6 @@ public: uint16 getNumSlices() const { return _numSlices; } uint16 getNumSamples() const { return _numSamples; } - - //--------------------------------------------------------------------- // Sub Mips manipulation // The number mips that a dimension could haves @@ -146,29 +144,21 @@ public: // If Bytes is NULL then simply allocate the space so mip sysmem can be accessed bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes); - template< typename T > T* editMip(uint16 level) { - Pixels* mip = accessStoredMip(level); - if (mip) { - return mip->sysmem.edit(); - } - return 0; - } - - template< typename T > const T* readMip(uint16 level) const { - const Pixels* mip = accessStoredMip(level); - if (mip) { - return mip->sysmem.read(); - } - return 0; - } - - bool isSysmemMipAvailable(uint16 level) const { - const Pixels* mip = accessStoredMip(level); + bool isStoredMipAvailable(uint16 level) const { + const PixelsPointer mip = accessStoredMip(level); if (mip) { return mip->_sysmem.isAvailable(); } return false; } + // Access the the sub mips + const PixelsPointer Texture::accessStoredMip(uint16 level) const { + if (level > _mips.size()) { + return 0; + } else { + return _mips[level]; + } + } // access sizes for the stored mips uint16 getStoredMipWidth(uint16 level) const; @@ -207,25 +197,16 @@ protected: Size resize(Type type, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices); - // Access the the sub mips - const Pixels* Texture::accessStoredMip(uint16 level) const { - if (level > _mips.size()) { - return 0; - } else { - return _mips[level].get(); - } - } - - // Access the the sub mips - Pixels* Texture::accessStoredMip(uint16 level) { - if (level > _mips.size()) { - return 0; - } else { - return _mips[level].get(); - } - } - void allocateStoredMip(uint16 level); + + // Access the the sub mips + PixelsPointer Texture::accessStoredMip(uint16 level) { + if (level > _mips.size()) { + return 0; + } else { + return _mips[level]; + } + } mutable GPUObject* _gpuObject = NULL; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index a91081ccdb..3163aa5f9c 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2351,7 +2351,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } } - GLBATCH(glPushMatrix)(); + // GLBATCH(glPushMatrix)(); const MeshState& state = _meshStates.at(i); if (state.clusterMatrices.size() > 1) { @@ -2388,7 +2388,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod // apply material properties if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + /// GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); } else { if (lastMaterialID != part.materialID) { @@ -2437,19 +2437,26 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } if (!mesh.tangents.isEmpty()) { - GLBATCH(glActiveTexture)(GL_TEXTURE1); + // GLBATCH(glActiveTexture)(GL_TEXTURE1); Texture* normalMap = networkPart.normalTexture.data(); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, !normalMap ? + /* GLBATCH(glBindTexture)(GL_TEXTURE_2D, !normalMap ? textureCache->getBlueTextureID() : normalMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); + */ + batch.setUniformTexture(1, !normalMap ? + textureCache->getBlueTexture() : normalMap->getGPUTexture()); + } if (locations->specularTextureUnit >= 0) { - GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->specularTextureUnit); + // GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->specularTextureUnit); Texture* specularMap = networkPart.specularTexture.data(); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, !specularMap ? + /* GLBATCH(glBindTexture)(GL_TEXTURE_2D, !specularMap ? textureCache->getWhiteTextureID() : specularMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); + */ + batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? + textureCache->getWhiteTexture() : specularMap->getGPUTexture()); } if (args) { @@ -2466,11 +2473,14 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod float emissiveScale = part.emissiveParams.y; GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); - GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); + // GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); Texture* emissiveMap = networkPart.emissiveTexture.data(); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ? + /* GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ? textureCache->getWhiteTextureID() : emissiveMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); + */ + batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? + textureCache->getWhiteTexture() : emissiveMap->getGPUTexture()); } lastMaterialID = part.materialID; @@ -2496,7 +2506,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } } - if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { + /* if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { GLBATCH(glActiveTexture)(GL_TEXTURE1); GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); GLBATCH(glActiveTexture)(GL_TEXTURE0); @@ -2513,8 +2523,8 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); GLBATCH(glActiveTexture)(GL_TEXTURE0); } - - GLBATCH(glPopMatrix)(); + */ + // GLBATCH(glPopMatrix)(); } diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 6c623d3eb7..c8bb936b27 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -167,7 +167,7 @@ static void loadSingleColorTexture(const unsigned char* color) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, color); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - +/* GLuint TextureCache::getWhiteTextureID() { if (_whiteTextureID == 0) { glGenTextures(1, &_whiteTextureID); @@ -177,7 +177,7 @@ GLuint TextureCache::getWhiteTextureID() { } return _whiteTextureID; } - +*/ const gpu::TexturePointer& TextureCache::getWhiteTexture() { if (_whiteTexture.isNull()) { _whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1)); @@ -185,7 +185,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() { } return _whiteTexture; } - +/* GLuint TextureCache::getBlueTextureID() { if (_blueTextureID == 0) { glGenTextures(1, &_blueTextureID); @@ -195,7 +195,7 @@ GLuint TextureCache::getBlueTextureID() { } return _blueTextureID; } - +*/ const gpu::TexturePointer& TextureCache::getBlueTexture() { if (_blueTexture.isNull()) { @@ -554,7 +554,7 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo finishedLoading(true); imageLoaded(image); - glBindTexture(GL_TEXTURE_2D, getID()); + /* glBindTexture(GL_TEXTURE_2D, getID()); if (image.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); @@ -566,7 +566,7 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - + */ if (image.hasAlphaChannel()) { _gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), image.width(), image.height())); _gpuTexture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA), image.byteCount(), image.constBits()); @@ -604,6 +604,7 @@ QSharedPointer DilatableNetworkTexture::getDilatedTexture(float dilatio painter.fillPath(path, Qt::black); painter.end(); + /* glBindTexture(GL_TEXTURE_2D, texture->getID()); if (dilatedImage.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 0, @@ -615,7 +616,7 @@ QSharedPointer DilatableNetworkTexture::getDilatedTexture(float dilatio glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - + */ if (dilatedImage.hasAlphaChannel()) { texture->_gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), dilatedImage.width(), dilatedImage.height())); texture->_gpuTexture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA), dilatedImage.byteCount(), dilatedImage.constBits()); diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index 9591218f80..97523d93d3 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -49,13 +49,13 @@ public: GLuint getPermutationNormalTextureID(); /// Returns the ID of an opaque white texture (useful for a default). - GLuint getWhiteTextureID(); + // GLuint getWhiteTextureID(); /// Returns an opaque white texture (useful for a default). const gpu::TexturePointer& getWhiteTexture(); /// Returns the ID of a pale blue texture (useful for a normal map). - GLuint getBlueTextureID(); + // GLuint getBlueTextureID(); /// Returns the ID of a pale blue texture (useful for a normal map). /// Returns an opaque white texture (useful for a default).