void GLPixelBuffer::blitFromTexture(GLTextureBuffer* src) { blitFromTexture(src, PixelVolume(0, 0, 0, src->getWidth(), src->getHeight(), src->getDepth()), PixelVolume(0, 0, 0, mWidth, mHeight, mDepth) ); }
//----------------------------------------------------------------------------- void GLESTextureBuffer::blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox) { GLESTextureBuffer *srct = static_cast<GLESTextureBuffer *>(src.getPointer()); // TODO: Check for FBO support first // Destination texture must be 2D // Source texture must be 2D if((src->getUsage() & TU_RENDERTARGET) == 0 && (srct->mTarget == GL_TEXTURE_2D)) { blitFromTexture(srct, srcBox, dstBox); } else { GLESHardwarePixelBuffer::blit(src, srcBox, dstBox); } }
//----------------------------------------------------------------------------- // blitFromMemory doing hardware trilinear scaling void GLESTextureBuffer::blitFromMemory(const PixelBox &src_orig, const Image::Box &dstBox) { // Fall back to normal GLHardwarePixelBuffer::blitFromMemory in case // - FBO is not supported // - Either source or target is luminance due doesn't looks like supported by hardware // - the source dimensions match the destination ones, in which case no scaling is needed if(!GL_OES_framebuffer_object || PixelUtil::isLuminance(src_orig.format) || PixelUtil::isLuminance(mFormat) || (src_orig.getWidth() == dstBox.getWidth() && src_orig.getHeight() == dstBox.getHeight() && src_orig.getDepth() == dstBox.getDepth())) { GLESHardwarePixelBuffer::blitFromMemory(src_orig, dstBox); return; } if(!mBuffer.contains(dstBox)) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Destination box out of range", "GLESTextureBuffer::blitFromMemory"); // For scoped deletion of conversion buffer MemoryDataStreamPtr buf; PixelBox src; // First, convert the srcbox to a OpenGL compatible pixel format if(GLESPixelUtil::getGLOriginFormat(src_orig.format) == 0) { // Convert to buffer internal format buf.bind(OGRE_NEW MemoryDataStream(PixelUtil::getMemorySize(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(), mFormat))); src = PixelBox(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(), mFormat, buf->getPtr()); PixelUtil::bulkPixelConversion(src_orig, src); } else { // No conversion needed src = src_orig; } // Create temporary texture to store source data GLuint id; GLenum target = GL_TEXTURE_2D; GLsizei width = GLESPixelUtil::optionalPO2(src.getWidth()); GLsizei height = GLESPixelUtil::optionalPO2(src.getHeight()); GLenum format = GLESPixelUtil::getClosestGLInternalFormat(src.format); GLenum datatype = GLESPixelUtil::getGLOriginDataType(src.format); // Generate texture name glGenTextures(1, &id); GL_CHECK_ERROR; // Set texture type glBindTexture(target, id); GL_CHECK_ERROR; // Set automatic mipmap generation; nice for minimisation glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE ); GL_CHECK_ERROR; // Allocate texture memory glTexImage2D(target, 0, format, width, height, 0, format, datatype, 0); GL_CHECK_ERROR; // GL texture buffer GLESTextureBuffer tex(BLANKSTRING, target, id, width, height, format, src.format, 0, 0, (Usage)(TU_AUTOMIPMAP|HBU_STATIC_WRITE_ONLY), false, false, 0); // Upload data to 0,0,0 in temporary texture Image::Box tempTarget(0, 0, 0, src.getWidth(), src.getHeight(), src.getDepth()); tex.upload(src, tempTarget); // Blit blitFromTexture(&tex, tempTarget, dstBox); // Delete temp texture glDeleteTextures(1, &id); GL_CHECK_ERROR; }
//----------------------------------------------------------------------------- // blitFromMemory doing hardware trilinear scaling void GLES2TextureBuffer::blitFromMemory(const PixelBox &src_orig, const Image::Box &dstBox) { // Fall back to normal GLHardwarePixelBuffer::blitFromMemory in case // - FBO is not supported // - Either source or target is luminance due doesn't looks like supported by hardware // - the source dimensions match the destination ones, in which case no scaling is needed // TODO: Check that extension is NOT available if(PixelUtil::isLuminance(src_orig.format) || PixelUtil::isLuminance(mFormat) || (src_orig.getWidth() == dstBox.getWidth() && src_orig.getHeight() == dstBox.getHeight() && src_orig.getDepth() == dstBox.getDepth())) { GLES2HardwarePixelBuffer::blitFromMemory(src_orig, dstBox); return; } if(!mBuffer.contains(dstBox)) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Destination box out of range", "GLES2TextureBuffer::blitFromMemory"); // For scoped deletion of conversion buffer MemoryDataStreamPtr buf; PixelBox src; // First, convert the srcbox to a OpenGL compatible pixel format if(GLES2PixelUtil::getGLOriginFormat(src_orig.format) == 0) { // Convert to buffer internal format buf.bind(OGRE_NEW MemoryDataStream(PixelUtil::getMemorySize(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(), mFormat))); src = PixelBox(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(), mFormat, buf->getPtr()); PixelUtil::bulkPixelConversion(src_orig, src); } else { // No conversion needed src = src_orig; } // Create temporary texture to store source data GLuint id; GLenum target = #if OGRE_NO_GLES3_SUPPORT == 0 (src.getDepth() != 1) ? GL_TEXTURE_3D : #endif GL_TEXTURE_2D; GLsizei width = GLES2PixelUtil::optionalPO2(src.getWidth()); GLsizei height = GLES2PixelUtil::optionalPO2(src.getHeight()); GLenum format = GLES2PixelUtil::getClosestGLInternalFormat(src.format); GLenum datatype = GLES2PixelUtil::getGLOriginDataType(src.format); // Generate texture name OGRE_CHECK_GL_ERROR(glGenTextures(1, &id)); // Set texture type OGRE_CHECK_GL_ERROR(glBindTexture(target, id)); #if GL_APPLE_texture_max_level && OGRE_PLATFORM != OGRE_PLATFORM_NACL OGRE_CHECK_GL_ERROR(glTexParameteri(target, GL_TEXTURE_MAX_LEVEL_APPLE, 1000 )); #elif OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 1000 )); #endif // Allocate texture memory #if OGRE_NO_GLES3_SUPPORT == 0 if(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) glTexImage3D(target, 0, src.format, src.getWidth(), src.getHeight(), src.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); else #endif OGRE_CHECK_GL_ERROR(glTexImage2D(target, 0, format, width, height, 0, format, datatype, 0)); // GL texture buffer GLES2TextureBuffer tex(StringUtil::BLANK, target, id, width, height, format, src.format, 0, 0, (Usage)(TU_AUTOMIPMAP|HBU_STATIC_WRITE_ONLY), false, false, 0); // Upload data to 0,0,0 in temporary texture Image::Box tempTarget(0, 0, 0, src.getWidth(), src.getHeight(), src.getDepth()); tex.upload(src, tempTarget); // Blit blitFromTexture(&tex, tempTarget, dstBox); // Delete temp texture OGRE_CHECK_GL_ERROR(glDeleteTextures(1, &id)); }