void D3D11TextureCube::CopyToSubTextureCube(Texture& target, uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { BOOST_ASSERT(type_ == target.Type()); D3D11Texture& other(*checked_cast<D3D11Texture*>(&target)); if ((src_width == dst_width) && (src_height == dst_height) && (this->Format() == target.Format())) { D3D11_BOX src_box; src_box.left = src_x_offset; src_box.top = src_y_offset; src_box.front = 0; src_box.right = src_x_offset + src_width; src_box.bottom = src_y_offset + src_height; src_box.back = 1; d3d_imm_ctx_->CopySubresourceRegion(other.D3DResource().get(), D3D11CalcSubresource(dst_level, dst_array_index * 6 + dst_face - CF_Positive_X, target.NumMipMaps()), dst_x_offset, dst_y_offset, 0, this->D3DResource().get(), D3D11CalcSubresource(src_level, src_array_index * 6 + src_face - CF_Positive_X, this->NumMipMaps()), &src_box); } else { this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, src_face, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } }
void D3D12TextureCube::CopyToTexture(Texture& target) { BOOST_ASSERT(type_ == target.Type()); if ((this->Width(0) == target.Width(0)) && (this->Format() == target.Format()) && (this->ArraySize() == target.ArraySize()) && (this->NumMipMaps() == target.NumMipMaps())) { this->DoHWCopyToTexture(target); } else { uint32_t const array_size = std::min(this->ArraySize(), target.ArraySize()); uint32_t const num_mips = std::min(this->NumMipMaps(), target.NumMipMaps()); for (uint32_t index = 0; index < array_size; ++ index) { for (int f = 0; f < 6; ++ f) { CubeFaces const face = static_cast<CubeFaces>(f); for (uint32_t level = 0; level < num_mips; ++ level) { this->ResizeTextureCube(target, index, face, level, 0, 0, target.Width(level), target.Height(level), index, face, level, 0, 0, this->Width(level), this->Height(level), true); } } } } }
void D3D11TextureCube::CopyToTexture(Texture& target) { BOOST_ASSERT(type_ == target.Type()); D3D11TextureCube& other(*checked_cast<D3D11TextureCube*>(&target)); if ((this->Width(0) == target.Width(0)) && (this->Format() == target.Format()) && (this->NumMipMaps() == target.NumMipMaps())) { d3d_imm_ctx_->CopyResource(other.D3DTexture().get(), d3dTextureCube_.get()); } else { uint32_t const array_size = std::min(this->ArraySize(), target.ArraySize()); uint32_t const num_mips = std::min(this->NumMipMaps(), target.NumMipMaps()); for (uint32_t index = 0; index < array_size; ++ index) { for (int f = 0; f < 6; ++ f) { CubeFaces const face = static_cast<CubeFaces>(f); for (uint32_t level = 0; level < num_mips; ++ level) { this->ResizeTextureCube(target, index, face, level, 0, 0, target.Width(level), target.Height(level), index, face, level, 0, 0, this->Width(level), this->Height(level), true); } } } } }
OGLESDepthStencilRenderView::OGLESDepthStencilRenderView(Texture& texture, int array_index, int level) : target_type_(checked_cast<OGLESTexture2D*>(&texture)->GLType()), array_index_(array_index), level_(level) { BOOST_ASSERT(Texture::TT_2D == texture.Type()); BOOST_ASSERT(IsDepthFormat(texture.Format())); if (array_index > 0) { THR(errc::function_not_supported); } width_ = texture.Width(level); height_ = texture.Height(level); pf_ = texture.Format(); tex_ = checked_cast<OGLESTexture2D*>(&texture)->GLTexture(); }
OGLESTextureCubeDepthStencilRenderView::OGLESTextureCubeDepthStencilRenderView(Texture& texture_cube, int array_index, Texture::CubeFaces face, int level) : texture_cube_(*checked_cast<OGLESTextureCube*>(&texture_cube)), face_(face), level_(level) { BOOST_ASSERT(Texture::TT_Cube == texture_cube.Type()); BOOST_ASSERT(IsDepthFormat(texture_cube.Format())); if (array_index > 0) { THR(errc::function_not_supported); } width_ = texture_cube.Width(level); height_ = texture_cube.Height(level); pf_ = texture_cube.Format(); tex_ = checked_cast<OGLESTextureCube*>(&texture_cube)->GLTexture(); }
Mapper(Texture& tex, uint32_t array_index, uint32_t level, TextureMapAccess tma, uint32_t x_offset, uint32_t width) : tex_(tex), mapped_array_index_(array_index), mapped_level_(level) { tex_.Map1D(array_index, level, tma, x_offset, width, data_); row_pitch_ = slice_pitch_ = width * NumFormatBytes(tex.Format()); }
OGLESTextureCubeRenderView::OGLESTextureCubeRenderView(Texture& texture_cube, int array_index, Texture::CubeFaces face, int level) : texture_cube_(*checked_cast<OGLESTextureCube*>(&texture_cube)), face_(face), level_(level) { UNREF_PARAM(array_index); BOOST_ASSERT(Texture::TT_Cube == texture_cube.Type()); BOOST_ASSERT(0 == array_index); uint32_t const channels = NumComponents(texture_cube.Format()); if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg()))) { THR(errc::function_not_supported); } tex_ = texture_cube_.GLTexture(); width_ = texture_cube_.Width(level); height_ = texture_cube_.Height(level); pf_ = texture_cube_.Format(); }
OGLESTexture3DRenderView::OGLESTexture3DRenderView(Texture& texture_3d, int array_index, uint32_t slice, int level) : texture_3d_(*checked_cast<OGLESTexture3D*>(&texture_3d)), slice_(slice), level_(level), copy_to_tex_(0) { UNREF_PARAM(array_index); BOOST_ASSERT(Texture::TT_3D == texture_3d.Type()); BOOST_ASSERT(texture_3d_.Depth(level) > slice); BOOST_ASSERT(0 == array_index); uint32_t const channels = NumComponents(texture_3d.Format()); if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg()))) { THR(errc::function_not_supported); } tex_ = texture_3d_.GLTexture(); width_ = texture_3d_.Width(level); height_ = texture_3d_.Height(level); pf_ = texture_3d_.Format(); }
void D3D12TextureCube::CopyToSubTextureCube(Texture& target, uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { BOOST_ASSERT(type_ == target.Type()); if ((src_width == dst_width) && (src_height == dst_height) && (this->Format() == target.Format())) { uint32_t const src_subres = CalcSubresource(src_level, src_array_index * 6 + src_face - CF_Positive_X, 0, this->NumMipMaps(), this->ArraySize() * 6); uint32_t const dst_subres = CalcSubresource(dst_level, dst_array_index * 6 + dst_face - CF_Positive_X, 0, target.NumMipMaps(), target.ArraySize() * 6); this->DoHWCopyToSubTexture(target, dst_subres, dst_x_offset, dst_y_offset, 0, src_subres, src_x_offset, src_y_offset, 0, src_width, src_height, 1); } else { this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, src_face, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } }
void D3D12TextureCube::CopyToSubTexture2D(Texture& target, uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { BOOST_ASSERT((TT_2D == target.Type()) || (TT_Cube == target.Type())); if ((src_width == dst_width) && (src_height == dst_height) && (this->Format() == target.Format())) { uint32_t const src_subres = CalcSubresource(src_level, src_array_index, 0, this->NumMipMaps(), this->ArraySize() * 6); uint32_t const dst_subres = CalcSubresource(dst_level, dst_array_index, 0, target.NumMipMaps(), target.ArraySize() * 6); this->DoHWCopyToSubTexture(target, dst_subres, dst_x_offset, dst_y_offset, 0, src_subres, src_x_offset, src_y_offset, 0, src_width, src_height, 1); } else { this->ResizeTexture2D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } }
OGLESTexture2DRenderView::OGLESTexture2DRenderView(Texture& texture_2d, int array_index, int level) : texture_2d_(*checked_cast<OGLESTexture2D*>(&texture_2d)), array_index_(array_index), level_(level) { BOOST_ASSERT(Texture::TT_2D == texture_2d.Type()); if (array_index > 0) { THR(errc::function_not_supported); } uint32_t const channels = NumComponents(texture_2d.Format()); if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg()))) { THR(errc::function_not_supported); } tex_ = texture_2d_.GLTexture(); width_ = texture_2d_.Width(level); height_ = texture_2d_.Height(level); pf_ = texture_2d_.Format(); }
void OGLESTextureCube::CopyToSubTextureCube(Texture& target, uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { BOOST_ASSERT(type_ == target.Type()); OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (glloader_GLES_VERSION_3_0() && (!IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_))))) { GLuint fbo_src, fbo_dst; re.GetFBOForBlit(fbo_src, fbo_dst); GLuint old_fbo = re.BindFramebuffer(); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src); if (array_size_ > 1) { glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index * 6 + src_face - CF_Positive_X); } else { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + src_face - CF_Positive_X, texture_, src_level); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst); if (target.ArraySize() > 1) { glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level, dst_array_index * 6 + dst_face - CF_Positive_X); } else { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + dst_face - CF_Positive_X, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level); } glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height, dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height, GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR); re.BindFramebuffer(old_fbo, true); } else { if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format())) { if (IsCompressedFormat(format_)) { BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3))); BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3))); BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3))); BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3))); Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, 0, 0, this->Width(src_level), this->Height(src_level)); Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, 0, 0, target.Width(dst_level), target.Height(dst_level)); uint32_t const block_size = NumFormatBytes(format_) * 4; uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_y_offset / 4) * mapper_src.RowPitch() + (src_x_offset / 4 * block_size); uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_y_offset / 4) * mapper_dst.RowPitch() + (dst_x_offset / 4 * block_size); for (uint32_t y = 0; y < src_height; y += 4) { std::memcpy(d, s, src_width / 4 * block_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } else { size_t const format_size = NumFormatBytes(format_); Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height); Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height); uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; ++ y) { std::memcpy(d, s, src_width * format_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } } else { this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, src_face, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } } }
void OGLESTexture2D::CopyToSubTexture2D(Texture& target, uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height, uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height) { BOOST_ASSERT(type_ == target.Type()); OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (glloader_GLES_VERSION_3_0() && ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_))))) { GLuint fbo_src, fbo_dst; re.GetFBOForBlit(fbo_src, fbo_dst); GLuint old_fbo = re.BindFramebuffer(); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src); if (array_size_ > 1) { glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index); } else { if (sample_count_ <= 1) { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level); } else { glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texture_); } } OGLESTexture& ogl_target = *checked_cast<OGLESTexture*>(&target); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst); if (array_size_ > 1) { glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index); } else { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLType(), ogl_target.GLTexture(), dst_level); } glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height, dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height, GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR); re.BindFramebuffer(old_fbo, true); } else if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format())) { GLint gl_internalFormat; GLenum gl_format; GLenum gl_type; OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_); GLint gl_target_internal_format; GLenum gl_target_format; GLenum gl_target_type; OGLESMapping::MappingFormat(gl_target_internal_format, gl_target_format, gl_target_type, target.Format()); if (IsCompressedFormat(format_)) { BOOST_ASSERT((src_width == dst_width) && (src_height == dst_height)); BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3))); BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3))); BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3))); BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3))); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height); uint32_t const block_size = NumFormatBytes(format_) * 4; uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; y += 4) { std::memcpy(d, s, src_width / 4 * block_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } else { size_t const format_size = NumFormatBytes(format_); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height); uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; ++ y) { std::memcpy(d, s, src_width * format_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } } else { this->ResizeTexture2D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height, src_array_index, src_level, src_x_offset, src_y_offset, src_width, src_height, true); } }
void OGLESTexture3D::CopyToSubTexture3D(Texture& target, uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_z_offset, uint32_t dst_width, uint32_t dst_height, uint32_t dst_depth, uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_z_offset, uint32_t src_width, uint32_t src_height, uint32_t src_depth) { KFL_UNUSED(dst_depth); BOOST_ASSERT(type_ == target.Type()); BOOST_ASSERT(0 == src_array_index); BOOST_ASSERT(0 == dst_array_index); if ((src_width == dst_width) && (src_height == dst_height) && (src_depth == dst_depth) && (format_ == target.Format())) { if (IsCompressedFormat(format_)) { BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3))); BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3))); BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3))); BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3))); for (uint32_t z = 0; z < src_depth; ++ z) { Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_z_offset + z, src_width, src_height, 1); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_z_offset + z, dst_width, dst_height, 1); uint32_t const block_size = NumFormatBytes(format_) * 4; uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; y += 4) { std::memcpy(d, s, src_width / 4 * block_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } } else { for (uint32_t z = 0; z < src_depth; ++ z) { size_t const format_size = NumFormatBytes(format_); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_z_offset + z, src_width, src_height, 1); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_z_offset + z, dst_width, dst_height, 1); uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); for (uint32_t y = 0; y < src_height; ++ y) { std::memcpy(d, s, src_width * format_size); s += mapper_src.RowPitch(); d += mapper_dst.RowPitch(); } } } } else { this->ResizeTexture3D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_z_offset, dst_width, dst_height, dst_depth, src_array_index, src_level, src_x_offset, src_y_offset, src_z_offset, src_width, src_height, src_depth, true); } }
void OGLTexture1D::CopyToSubTexture1D(Texture& target, uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_width, uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_width) { BOOST_ASSERT(type_ == target.Type()); if ((format_ == target.Format()) && !IsCompressedFormat(format_) && (glloader_GL_VERSION_4_3() || glloader_GL_ARB_copy_image()) && (src_width == dst_width) && (1 == sample_count_)) { OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target); glCopyImageSubData( texture_, target_type_, src_level, src_x_offset, 0, src_array_index, ogl_target.GLTexture(), ogl_target.GLType(), dst_level, dst_x_offset, 0, dst_array_index, src_width, 1, 1); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GL_ARB_texture_rg() || (4 == NumComponents(format_)))) { GLuint fbo_src, fbo_dst; re.GetFBOForBlit(fbo_src, fbo_dst); GLuint old_fbo = re.BindFramebuffer(); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src); if (array_size_ > 1) { glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index); } else { if (sample_count_ <= 1) { glFramebufferTexture1D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level); } else { glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texture_); } } OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst); if (array_size_ > 1) { glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index); } else { glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, ogl_target.GLTexture(), dst_level); } glBlitFramebuffer(src_x_offset, 0, src_x_offset + src_width, 1, dst_x_offset, 0, dst_x_offset + dst_width, 1, GL_COLOR_BUFFER_BIT, (src_width == dst_width) ? GL_NEAREST : GL_LINEAR); re.BindFramebuffer(old_fbo, true); } else { if ((src_width == dst_width) && (format_ == target.Format())) { if (IsCompressedFormat(format_)) { BOOST_ASSERT(0 == (src_x_offset & 0x3)); BOOST_ASSERT(0 == (dst_x_offset & 0x3)); BOOST_ASSERT(0 == (src_width & 0x3)); BOOST_ASSERT(0 == (dst_width & 0x3)); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, 0, this->Width(src_level)); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, 0, target.Width(dst_level)); uint32_t const block_size = NumFormatBytes(format_) * 4; uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_x_offset / 4 * block_size); uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_x_offset / 4 * block_size); std::memcpy(d, s, src_width / 4 * block_size); } else { size_t const format_size = NumFormatBytes(format_); Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_width); Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_width); uint8_t const * s = mapper_src.Pointer<uint8_t>(); uint8_t* d = mapper_dst.Pointer<uint8_t>(); std::memcpy(d, s, src_width * format_size); } } else { this->ResizeTexture1D(target, dst_array_index, dst_level, dst_x_offset, dst_width, src_array_index, src_level, src_x_offset, src_width, true); } } } }
static bool LoadTex(char * FileName, unsigned char scdata [lmwid][lmwid][3]){ using namespace VSFileSystem; unsigned char ctemp; VSFile f; VSError err = f.OpenReadOnly( FileName, TextureFile); if (err>Ok) { return false; } Texture tex; unsigned char * data = tex.ReadImage( &f, texTransform, true); int bpp = tex.Depth(); int format = tex.Format(); unsigned char *buffer= NULL; bpp/=8; // 999 is the code for DDS file, we must decompress them. if(format == 999){ unsigned char *tmpbuffer = data + 2; TEXTUREFORMAT internformat; bpp = 1; // Make sure we are reading a DXT1 file. All backgrounds // should be DXT1 switch(tex.mode){ case ::VSImage::_DXT1: internformat = DXT1; break; default: return(false); } // we could hardware decompress, but that involves more // pollution of gl in gfx. ddsDecompress(tmpbuffer,buffer,internformat, tex.sizeY,tex.sizeX); // We are done with the DDS file data. Remove it. free(data); data = buffer; // stride and row_pointers are used for the texTransform unsigned long stride = 4 * sizeof(unsigned char); unsigned char **row_pointers = (unsigned char**)malloc(sizeof(unsigned char*)*tex.sizeY); for(unsigned int i = 0;i < tex.sizeY;++i){ row_pointers[i] = &data[i*stride*tex.sizeX]; } // texTransform demands that the first argument (bpp) be 8. So we abide int tmp = 8; int tmp2 = PNG_HAS_COLOR + PNG_HAS_ALPHA; buffer = texTransform(tmp,tmp2,tex.sizeX,tex.sizeY,row_pointers); // We're done with row_pointers, free it free(row_pointers); row_pointers = NULL; // We're done with the decompressed dds data, free it free(data); // We set data to the transformed image data data = buffer; buffer = NULL; // it's 3 because 24/8 bpp = 4; } else if (format&PNG_HAS_ALPHA) { bpp*=4; }else { bpp*=3; } if (data) { int ii; int jj; for (int i=0;i<lmwid;i++) { ii=(i*tex.sizeY)/lmwid; for (int j=0;j<lmwid;j++) { jj= (j*tex.sizeX)/lmwid; scdata[i][j][0]=data[(ii*tex.sizeX+jj)*bpp]; scdata[i][j][1]=data[(ii*tex.sizeX+jj)*bpp+1]; scdata[i][j][2]=data[(ii*tex.sizeX+jj)*bpp+2]; } } free(data); } else return false; f.Close(); return true; }