From f91fdcbdf9dd4ee25fa3c5fc481e12a9ea01504f Mon Sep 17 00:00:00 2001 From: Lars Ivar Hatledal Date: Mon, 6 May 2024 22:34:52 +0200 Subject: [PATCH] add functionality for reading texture data back into memory --- include/threepp/renderers/GLRenderer.hpp | 3 +++ src/threepp/renderers/GLRenderTarget.cpp | 2 +- src/threepp/renderers/GLRenderer.cpp | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/threepp/renderers/GLRenderer.hpp b/include/threepp/renderers/GLRenderer.hpp index ee063257..30eb544b 100644 --- a/include/threepp/renderers/GLRenderer.hpp +++ b/include/threepp/renderers/GLRenderer.hpp @@ -152,6 +152,9 @@ namespace threepp { void readPixels(const Vector2& position, const WindowSize& size, Format format, unsigned char* data); + // Experimental threepp function + void copyTextureToImage(Texture& texture); + void resetState(); void invokeLater(const std::function& task, float delay = 0); diff --git a/src/threepp/renderers/GLRenderTarget.cpp b/src/threepp/renderers/GLRenderTarget.cpp index 6b6c7800..fe888264 100644 --- a/src/threepp/renderers/GLRenderTarget.cpp +++ b/src/threepp/renderers/GLRenderTarget.cpp @@ -17,7 +17,7 @@ GLRenderTarget::GLRenderTarget(unsigned int width, unsigned int height, const GL scissor(0.f, 0.f, static_cast(width), static_cast(height)), viewport(0.f, 0.f, static_cast(width), static_cast(height)), depthBuffer(options.depthBuffer), stencilBuffer(options.stencilBuffer), depthTexture(options.depthTexture), - texture(Texture::create({})) { + texture(Texture::create({Image({}, width, height)})) { if (options.mapping) texture->mapping = *options.mapping; if (options.wrapS) texture->wrapS = *options.wrapS; diff --git a/src/threepp/renderers/GLRenderer.cpp b/src/threepp/renderers/GLRenderer.cpp index 08db588a..c90864c1 100644 --- a/src/threepp/renderers/GLRenderer.cpp +++ b/src/threepp/renderers/GLRenderer.cpp @@ -1128,6 +1128,22 @@ struct GLRenderer::Impl { glReadPixels(static_cast(position.x), static_cast(position.y), size.width, size.width, glFormat, GL_UNSIGNED_BYTE, data); } + void copyTextureToImage(Texture& texture) { + + textures.setTexture2D(texture, 0); + + auto& image = texture.image.front(); + auto& data = image.data(); + if (data.empty()) { + auto newSize = image.width * image.height * (texture.format == Format::RGB ? 3 : 4); + data.resize(newSize); + } + + glGetTexImage(GL_TEXTURE_2D, 0, gl::toGLFormat(texture.format), gl::toGLType(texture.type), data.data()); + + state.unbindTexture(); + } + void setViewport(int x, int y, int width, int height) { _viewport.set(static_cast(x), static_cast(y), static_cast(width), static_cast(height)); @@ -1348,6 +1364,11 @@ void GLRenderer::readPixels(const Vector2& position, const WindowSize& size, For pimpl_->readPixels(position, size, format, data); } +void GLRenderer::copyTextureToImage(Texture& texture) { + + pimpl_->copyTextureToImage(texture); +} + void GLRenderer::resetState() { pimpl_->reset();