extern "C" int load_crn_to_texture_array(int slot, unsigned char *data, size_t length) { crnd::crn_level_info level_info; crnd::crnd_unpack_context cuc = crnd::crnd_unpack_begin(data, length); if (!crnd::crnd_get_level_info(data, length, 0, &level_info)) return 0; size_t size = level_info.m_blocks_x * level_info.m_blocks_y * level_info.m_bytes_per_block; unsigned char *output = (unsigned char *) malloc(size); for (int level=0; level < 13; ++level) { if (!crnd::crnd_get_level_info(data, length, level, &level_info)) break; unsigned int pitch_bytes = level_info.m_blocks_x * level_info.m_bytes_per_block; if (!crnd::crnd_unpack_level(cuc, (void **) &output, size, pitch_bytes, level)) break; glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY_EXT, level, 0,0,slot, level_info.m_width, level_info.m_height,1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, pitch_bytes*level_info.m_blocks_y, output); } free(output); crnd::crnd_unpack_end(cuc); return 1; }
void APIENTRY FWGLExtension::initCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { spCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3D)FW_GETGLPROC("glCompressedTexSubImage3D"); if(!spCompressedTexSubImage3D) reportError("glCompressedTexSubImage3D"); glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); }
inline void VL_glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) { if (glCompressedTexSubImage3D) glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); else VL_UNSUPPORTED_FUNC(); }
void Texture2DArray::setCompressedSubImage(int level, int x, int y, int l, int w, int h, int d, int s, const Buffer &pixels) { bindToTextureUnit(); pixels.bind(GL_PIXEL_UNPACK_BUFFER); glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, x, y, l, w, h, d, getTextureInternalFormat(internalFormat), s, pixels.data(0)); pixels.unbind(GL_PIXEL_UNPACK_BUFFER); assert(FrameBuffer::getError() == GL_NO_ERROR); }
void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits) { GLint oldTexture; glGetIntegerv(bindingTarget, &oldTexture); glBindTexture(target, texture); glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits); glBindTexture(target, oldTexture); }
void OGLESTexture2D::Unmap2D(uint32_t array_index, uint32_t level) { switch (last_tma_) { case TMA_Read_Only: break; case TMA_Write_Only: case TMA_Read_Write: { GLint gl_internalFormat; GLenum gl_format; GLenum gl_type; OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_); uint32_t const w = this->Width(level); uint32_t const h = this->Height(level); OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindTexture(0, target_type_, texture_); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size; if (array_size_ > 1) { glCompressedTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1, gl_format, image_size, &tex_data_[array_index * num_mip_maps_ + level][0]); } else { glCompressedTexSubImage2D(target_type_, level, 0, 0, w, h, gl_format, image_size, &tex_data_[array_index * num_mip_maps_ + level][0]); } } else { if (array_size_ > 1) { glTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1, gl_format, gl_type, &tex_data_[array_index * num_mip_maps_ + level][0]); } else { glTexSubImage2D(target_type_, level, 0, 0, w, h, gl_format, gl_type, &tex_data_[array_index * num_mip_maps_ + level][0]); } } } break; default: BOOST_ASSERT(false); break; } }
void OpenGLTexture2D::CreateWithImmutableStorage(ElementInitData* initData) { GLenum internalFormat, externFormat, formatType; OpenGLMapping::Mapping(internalFormat, externFormat, formatType, mFormat); uint32_t texelSize = PixelFormatUtils::GetNumElemBytes(mFormat); if (mTextureArraySize > 1) { glTexStorage3D(mTextureTarget, mMipLevels, internalFormat, mWidth, mHeight, mTextureArraySize); if (initData) { for (uint32_t arrIndex = 0; arrIndex < mTextureArraySize; ++ arrIndex) { for (uint32_t level = 0; level < mMipLevels; ++ level) { uint32_t levelWidth = (std::max)(1U, mWidth >> level); uint32_t levelHeight = (std::max)(1U, mHeight >> level); if (PixelFormatUtils::IsCompressed(mFormat)) { int blockSize = (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; uint32_t imageSize = ((levelWidth+3)/4)*((levelHeight+3)/4)*blockSize; glCompressedTexSubImage3D(mTextureTarget, static_cast<GLint>(level), 0, 0, static_cast<GLint>(arrIndex), static_cast<GLsizei>(levelWidth), static_cast<GLsizei>(levelHeight), static_cast<GLsizei>(0), externFormat, static_cast<GLsizei>(imageSize), initData[arrIndex * mMipLevels + level].pData); } else { glTexSubImage3D(mTextureTarget, static_cast<GLint>(level), 0, 0, static_cast<GLint>(arrIndex), static_cast<GLsizei>(levelWidth), static_cast<GLsizei>(levelHeight), static_cast<GLsizei>(1), externFormat, formatType, initData[arrIndex * mMipLevels + level].pData); } } } } }
static void GLTexSubImage3DBase( GLenum target, std::uint32_t mipLevel, std::int32_t x, std::int32_t y, std::int32_t z, std::uint32_t width, std::uint32_t height, std::uint32_t depth, const SrcImageDescriptor& imageDesc) { if (IsCompressedFormat(imageDesc.format)) { glCompressedTexSubImage3D( target, static_cast<GLint>(mipLevel), x, y, z, static_cast<GLsizei>(width), static_cast<GLsizei>(height), static_cast<GLsizei>(depth), GLTypes::Map(imageDesc.format), static_cast<GLsizei>(imageDesc.dataSize), imageDesc.data ); } else { glTexSubImage3D( target, static_cast<GLint>(mipLevel), x, y, z, static_cast<GLsizei>(width), static_cast<GLsizei>(height), static_cast<GLsizei>(depth), GLTypes::Map(imageDesc.format), GLTypes::Map(imageDesc.dataType), imageDesc.data ); } }
// ------------------------------------------------------------------------------------------------ void Texture2DContainer::CompressedTexSubImage3D(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data) { glBindTexture(GL_TEXTURE_2D_ARRAY, mTexId); glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); }
void OGLESTextureCube::CreateHWResource(ElementInitData const * init_data) { uint32_t texel_size = NumFormatBytes(format_); GLint glinternalFormat; GLenum glformat; GLenum gltype; OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_); glBindTexture(target_type_, texture_); for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (int face = 0; face < 6; ++ face) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const s = this->Width(level); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((s + 3) / 4) * ((s + 3) / 4) * block_size; void* ptr; if (nullptr == init_data) { tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0); ptr = nullptr; } else { tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size); std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0], init_data[(array_index * 6 + face) * num_mip_maps_ + level].data, image_size); ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0]; } if (array_size_ > 1) { if (0 == array_index) { glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, array_size_, 0, image_size * array_size_, nullptr); } if (init_data != nullptr) { glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1, glformat, image_size, init_data[(array_index * 6 + face) * num_mip_maps_ + level].data); } } else { glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, 0, image_size, ptr); } } else { GLsizei const image_size = s * s * texel_size; void* ptr; if (nullptr == init_data) { tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0); ptr = nullptr; } else { tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size); std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0], init_data[face * num_mip_maps_ + level].data, image_size); ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0]; } if (array_size_ > 1) { if (0 == array_index) { glTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, array_size_, 0, glformat, gltype, nullptr); } if (init_data != nullptr) { glTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1, glformat, gltype, init_data[array_index * num_mip_maps_ + level].data); } } else { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, 0, glformat, gltype, ptr); } } } } } hw_res_ready_ = true; }
bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data) { URHO3D_PROFILE(SetTextureData); if (!object_.name_ || !graphics_) { URHO3D_LOGERROR("Texture array not created, can not set data"); return false; } if (!data) { URHO3D_LOGERROR("Null source for setting data"); return false; } if (layer >= layers_) { URHO3D_LOGERROR("Illegal layer for setting data"); return false; } if (level >= levels_) { URHO3D_LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { URHO3D_LOGWARNING("Texture array data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0) { URHO3D_LOGERROR("Illegal dimensions for setting data"); return false; } graphics_->SetTextureForUpdate(this); #ifndef GL_ES_VERSION_2_0 bool wholeLevel = x == 0 && y == 0 && width == levelWidth && height == levelHeight && layer == 0; unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; if (!IsCompressed()) { if (wholeLevel) glTexImage3D(target_, level, format, width, height, layers_, 0, GetExternalFormat(format_), GetDataType(format_), 0); glTexSubImage3D(target_, level, x, y, layer, width, height, 1, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage3D(target_, level, format, width, height, layers_, 0, GetDataSize(width, height, layers_), 0); glCompressedTexSubImage3D(target_, level, x, y, layer, width, height, 1, format, GetDataSize(width, height), data); } #endif graphics_->SetTexture(0, 0); return true; }
void GLTextureBuffer::upload(const PixelData& data, const PixelVolume& dest) { if ((mUsage & TU_DEPTHSTENCIL) != 0) { LOGERR("Writing to depth stencil texture from CPU not supported."); return; } glBindTexture(mTarget, mTextureID); BS_CHECK_GL_ERROR(); if(PixelUtil::isCompressed(data.getFormat())) { // Block-compressed data cannot be smaller than 4x4, and must be a multiple of 4 const UINT32 actualWidth = Math::divideAndRoundUp(std::max(mWidth, 4U), 4U) * 4U; const UINT32 actualHeight = Math::divideAndRoundUp(std::max(mHeight, 4U), 4U) * 4U; const UINT32 expectedRowPitch = actualWidth; const UINT32 expectedSlicePitch = actualWidth * actualHeight; const bool isConsecutive = data.getRowPitch() == expectedRowPitch && data.getSlicePitch() == expectedSlicePitch; if (data.getFormat() != mFormat || !isConsecutive) { LOGERR("Compressed images must be consecutive, in the source format"); return; } GLenum format = GLPixelUtil::getGLInternalFormat(mFormat, mHwGamma); switch(mTarget) { case GL_TEXTURE_1D: glCompressedTexSubImage1D(GL_TEXTURE_1D, mLevel, dest.left, dest.getWidth(), format, data.getConsecutiveSize(), data.getData()); BS_CHECK_GL_ERROR(); break; case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: glCompressedTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), format, data.getConsecutiveSize(), data.getData()); BS_CHECK_GL_ERROR(); break; case GL_TEXTURE_3D: glCompressedTexSubImage3D(GL_TEXTURE_3D, mLevel, dest.left, dest.top, dest.front, dest.getWidth(), dest.getHeight(), dest.getDepth(), format, data.getConsecutiveSize(), data.getData()); BS_CHECK_GL_ERROR(); break; default: break; } } else { if (data.getWidth() != data.getRowPitch()) { glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch()); BS_CHECK_GL_ERROR(); } if (data.getHeight()*data.getWidth() != data.getSlicePitch()) { glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch() / data.getWidth())); BS_CHECK_GL_ERROR(); } if (data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0) { glPixelStorei( GL_UNPACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront()); BS_CHECK_GL_ERROR(); } if ((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); BS_CHECK_GL_ERROR(); } switch(mTarget) { case GL_TEXTURE_1D: glTexSubImage1D(GL_TEXTURE_1D, mLevel, dest.left, dest.getWidth(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); BS_CHECK_GL_ERROR(); break; case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); BS_CHECK_GL_ERROR(); break; case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_3D: glTexSubImage3D( mTarget, mLevel, dest.left, dest.top, dest.front, dest.getWidth(), dest.getHeight(), dest.getDepth(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); BS_CHECK_GL_ERROR(); break; } } // Restore defaults glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); BS_CHECK_GL_ERROR(); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); BS_CHECK_GL_ERROR(); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); BS_CHECK_GL_ERROR(); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); BS_CHECK_GL_ERROR(); BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture); }
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { if (!object_ || !graphics_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } graphics_->SetTextureForUpdate(this); bool wholeLevel = x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth; unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; #ifndef GL_ES_VERSION_2_0 if (!IsCompressed()) { if (wholeLevel) glTexImage3D(target_, level, format, width, height, depth, 0, GetExternalFormat(format_), GetDataType(format_), data); else glTexSubImage3D(target_, level, x, y, z, width, height, depth, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage3D(target_, level, format, width, height, depth, 0, GetDataSize(width, height, depth), data); else glCompressedTexSubImage3D(target_, level, x, y, z, width, height, depth, format, GetDataSize(width, height, depth), data); } #endif graphics_->SetTexture(0, 0); return true; }
void OGLESTexture2D::CreateHWResource(ElementInitData const * init_data) { uint32_t texel_size = NumFormatBytes(format_); GLint glinternalFormat; GLenum glformat; GLenum gltype; OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_); glBindTexture(target_type_, texture_); for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const w = this->Width(level); uint32_t const h = this->Height(level); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size; void* ptr; if (nullptr == init_data) { tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0); ptr = nullptr; } else { tex_data_[array_index * num_mip_maps_ + level].resize(image_size); std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0], init_data[array_index * num_mip_maps_ + level].data, image_size); ptr = &tex_data_[array_index * num_mip_maps_ + level][0]; } if (array_size_ > 1) { if (0 == array_index) { glCompressedTexImage3D(target_type_, level, glinternalFormat, w, h, array_size_, 0, image_size * array_size_, nullptr); } if (init_data != nullptr) { glCompressedTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1, glformat, image_size, init_data[array_index * num_mip_maps_ + level].data); } } else { glCompressedTexImage2D(target_type_, level, glinternalFormat, w, h, 0, image_size, ptr); } } else { GLsizei const image_size = w * h * texel_size; void* ptr; if (nullptr == init_data) { tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0); ptr = nullptr; } else { tex_data_[array_index * num_mip_maps_ + level].resize(image_size); std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0], init_data[array_index * num_mip_maps_ + level].data, image_size); ptr = &tex_data_[array_index * num_mip_maps_ + level][0]; } if (array_size_ > 1) { if (0 == array_index) { glTexImage3D(target_type_, level, glinternalFormat, w, h, array_size_, 0, glformat, gltype, nullptr); } if (init_data != nullptr) { glTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1, glformat, gltype, init_data[array_index * num_mip_maps_ + level].data); } } else { glTexImage2D(target_type_, level, glinternalFormat, w, h, 0, glformat, gltype, ptr); } } } } hw_res_ready_ = true; }
DDSTexture::DDSTexture(string filename) { filename = FOLDER + filename; gli::texture texture = gli::load(filename); if (texture.empty()) return; gli::gl GL; gli::gl::format const Format = GL.translate(texture.format()); this->target = GL.translate(texture.target()); glGenTextures(1, &glId); glBindTexture(target, glId); glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(texture.levels() - 1)); glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, Format.Swizzle[0]); glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, Format.Swizzle[1]); glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, Format.Swizzle[2]); glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, Format.Swizzle[3]); glm::tvec3<GLsizei> const Dimensions(texture.dimensions()); GLsizei const FaceTotal = static_cast<GLsizei>(texture.layers() * texture.faces()); switch (texture.target()) { case gli::TARGET_1D: glTexStorage1D(target, static_cast<GLint>(texture.levels()), Format.Internal, Dimensions.x); break; case gli::TARGET_1D_ARRAY: case gli::TARGET_2D: case gli::TARGET_CUBE: glTexStorage2D( target, static_cast<GLint>(texture.levels()), Format.Internal, Dimensions.x, texture.target() == gli::TARGET_2D ? Dimensions.y : FaceTotal); break; case gli::TARGET_2D_ARRAY: case gli::TARGET_3D: case gli::TARGET_CUBE_ARRAY: glTexStorage3D( target, static_cast<GLint>(texture.levels()), Format.Internal, Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : FaceTotal); break; default: assert(0); break; } for (std::size_t Layer = 0; Layer < texture.layers(); ++Layer) { for (std::size_t Face = 0; Face < texture.faces(); ++Face) { for (std::size_t Level = 0; Level < texture.levels(); ++Level) { GLsizei const LayerGL = static_cast<GLsizei>(Layer); glm::tvec3<GLsizei> Dimensions(texture.dimensions(Level)); if (gli::is_target_cube(texture.target())) target = static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + Face); switch (texture.target()) { case gli::TARGET_1D: if (gli::is_compressed(texture.format())) glCompressedTexSubImage1D( target, static_cast<GLint>(Level), 0, Dimensions.x, Format.Internal, static_cast<GLsizei>(texture.size(Level)), texture.data(Layer, Face, Level)); else glTexSubImage1D( target, static_cast<GLint>(Level), 0, Dimensions.x, Format.External, Format.Type, texture.data(Layer, Face, Level)); break; case gli::TARGET_1D_ARRAY: case gli::TARGET_2D: case gli::TARGET_CUBE: if (gli::is_compressed(texture.format())) glCompressedTexSubImage2D( target, static_cast<GLint>(Level), 0, 0, Dimensions.x, texture.target() == gli::TARGET_1D_ARRAY ? 0 : Dimensions.y, Format.Internal, static_cast<GLsizei>(texture.size(Level)), texture.data(Layer, Face, Level)); else glTexSubImage2D( target, static_cast<GLint>(Level), 0, 0, Dimensions.x, texture.target() == gli::TARGET_1D_ARRAY ? LayerGL : Dimensions.y, Format.External, Format.Type, texture.data(Layer, Face, Level)); break; case gli::TARGET_2D_ARRAY: case gli::TARGET_3D: case gli::TARGET_CUBE_ARRAY: if (gli::is_compressed(texture.format())) glCompressedTexSubImage3D( target, static_cast<GLint>(Level), 0, 0, 0, Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : LayerGL, Format.Internal, static_cast<GLsizei>(texture.size(Level)), texture.data(Layer, Face, Level)); else glTexSubImage3D( target, static_cast<GLint>(Level), 0, 0, 0, Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : LayerGL, Format.External, Format.Type, texture.data(Layer, Face, Level)); break; default: assert(0); break; } } } } glGenerateMipmap(target); glBindTexture(target, 0); }
void GLTextureBuffer::upload(const PixelData &data, const PixelVolume &dest) { if((mUsage & TU_RENDERTARGET) != 0) BS_EXCEPT(NotImplementedException, "Writing to render texture from CPU not supported."); if ((mUsage & TU_DEPTHSTENCIL) != 0) BS_EXCEPT(NotImplementedException, "Writing to depth stencil texture from CPU not supported."); glBindTexture( mTarget, mTextureID ); if(PixelUtil::isCompressed(data.getFormat())) { if(data.getFormat() != mFormat || !data.isConsecutive()) BS_EXCEPT(InvalidParametersException, "Compressed images must be consecutive, in the source format"); GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat); switch(mTarget) { case GL_TEXTURE_1D: if (dest.left == 0) { glCompressedTexImage1D(GL_TEXTURE_1D, mLevel, format, dest.getWidth(), 0, data.getConsecutiveSize(), data.getData()); } else { glCompressedTexSubImage1D(GL_TEXTURE_1D, mLevel, dest.left, dest.getWidth(), format, data.getConsecutiveSize(), data.getData()); } break; case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: if (dest.left == 0 && dest.top == 0) { glCompressedTexImage2D(mFaceTarget, mLevel, format, dest.getWidth(), dest.getHeight(), 0, data.getConsecutiveSize(), data.getData()); } else { glCompressedTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), format, data.getConsecutiveSize(), data.getData()); } break; case GL_TEXTURE_3D: if (dest.left == 0 && dest.top == 0 && dest.front == 0) { glCompressedTexImage3D(GL_TEXTURE_3D, mLevel, format, dest.getWidth(), dest.getHeight(), dest.getDepth(), 0, data.getConsecutiveSize(), data.getData()); } else { glCompressedTexSubImage3D(GL_TEXTURE_3D, mLevel, dest.left, dest.top, dest.front, dest.getWidth(), dest.getHeight(), dest.getDepth(), format, data.getConsecutiveSize(), data.getData()); } break; } } else { if(data.getWidth() != data.getRowPitch()) glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch()); if(data.getHeight()*data.getWidth() != data.getSlicePitch()) glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth())); if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0) glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront()); if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); switch(mTarget) { case GL_TEXTURE_1D: glTexSubImage1D(GL_TEXTURE_1D, mLevel, dest.left, dest.getWidth(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); break; case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); break; case GL_TEXTURE_3D: glTexSubImage3D( GL_TEXTURE_3D, mLevel, dest.left, dest.top, dest.front, dest.getWidth(), dest.getHeight(), dest.getDepth(), GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData()); break; } } // Restore defaults glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture); }
PIGLIT_GL_TEST_CONFIG_END static bool test_getsubimage(GLenum target, GLsizei width, GLsizei height, GLsizei numSlices, GLenum intFormat) { const GLint bufSize = width * height * 4 * sizeof(GLubyte); GLubyte *texData; GLubyte *refData = malloc(6 * bufSize); /* 6 for cubemaps */ GLubyte *testData = malloc(6 * bufSize); /* 6 for cubemaps */ GLuint tex; int i, slice, compressedSize, compSize; int blockWidth, blockHeight, blockSize; bool pass = true; const int level = 0; int x0, y0, x1, y1, w0, h0, w1, h1; printf("Testing %s %s %d x %d\n", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(intFormat), width, height); /* For all S3TC formats */ blockWidth = blockHeight = 4; if (intFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || intFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { blockSize = 8; } else { assert(intFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || intFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); blockSize = 16; } /* Size must be multiple of block dims */ assert(width % blockWidth == 0); assert(height % blockHeight == 0); compressedSize = (width / blockWidth) * (height / blockHeight) * blockSize; if (0) { printf("byte per block row: %d\n", (width / blockWidth) * blockSize); printf("compressed image size = %d\n", compressedSize); } /* initial texture data */ texData = malloc(compressedSize); for (i = 0; i < compressedSize; i++) { texData[i] = (i+10) & 0xff; } glGenTextures(1, &tex); glBindTexture(target, tex); /* Define texture image */ if (target == GL_TEXTURE_CUBE_MAP) { for (slice = 0; slice < 6; slice++) { glCompressedTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice, level, intFormat, width, height, 0, compressedSize, texData); } glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); assert(numSlices == 6); } else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) { assert(numSlices % 6 == 0); glCompressedTexImage3D(target, level, intFormat, width, height, numSlices, 0, compressedSize * numSlices, NULL); for (slice = 0; slice < numSlices; slice++) { glCompressedTexSubImage3D(target, level, 0, 0, slice, width, height, 1, intFormat, compressedSize, texData); } glGetTexLevelParameteriv(target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); compSize /= numSlices; } else if (target == GL_TEXTURE_2D_ARRAY) { glCompressedTexImage3D(target, level, intFormat, width, height, numSlices, 0, compressedSize * numSlices, NULL); for (slice = 0; slice < numSlices; slice++) { glCompressedTexSubImage3D(target, level, 0, 0, slice, width, height, 1, intFormat, compressedSize, texData); } glGetTexLevelParameteriv(target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); compSize /= numSlices; } else { assert(target == GL_TEXTURE_2D); glCompressedTexImage2D(target, level, intFormat, width, height, 0, compressedSize, texData); glGetTexLevelParameteriv(target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); assert(numSlices == 1); } assert(compSize == compressedSize); /* Should be no GL errors */ if (!piglit_check_gl_error(GL_NO_ERROR)) { pass = false; } refData = calloc(1, numSlices * compressedSize); testData = calloc(1, numSlices * compressedSize); /* compute pos/size of sub-regions */ x0 = 0; y0 = 0; x1 = width / 4; /* quarter width */ y1 = height / 2; /* half height */ /* Position must be multiple of block dims */ assert(x1 % blockWidth == 0); assert(y1 % blockHeight == 0); w0 = x1 - x0; w1 = width - x1; h0 = y1 - y0; h1 = height - y1; /* Sizes must be multiple of block dims */ assert(w0 % blockWidth == 0); assert(w1 % blockWidth == 0); assert(h0 % blockHeight == 0); assert(h1 % blockHeight == 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, width); glPixelStorei(GL_PACK_IMAGE_HEIGHT, height); glPixelStorei(GL_PACK_COMPRESSED_BLOCK_WIDTH, blockWidth); glPixelStorei(GL_PACK_COMPRESSED_BLOCK_HEIGHT, blockHeight); glPixelStorei(GL_PACK_COMPRESSED_BLOCK_SIZE, blockSize); /* Should be no GL errors */ if (!piglit_check_gl_error(GL_NO_ERROR)) { pass = false; } /* * Get whole compressed image (the reference) */ if (target == GL_TEXTURE_CUBE_MAP) { for (slice = 0; slice < 6; slice++) { glGetCompressedTexImage( GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice, level, refData + slice * compressedSize); } } else { glGetCompressedTexImage(target, level, refData); } if (!piglit_check_gl_error(GL_NO_ERROR)) { pass = false; } /* * Now get four sub-regions which should be equivalent * to the whole reference image. */ /* lower-left */ glPixelStorei(GL_PACK_SKIP_PIXELS, x0); glPixelStorei(GL_PACK_SKIP_ROWS, y0); glGetCompressedTextureSubImage(tex, level, x0, y0, 0, w0, h0, numSlices, numSlices * compressedSize, testData); /* lower-right */ glPixelStorei(GL_PACK_SKIP_PIXELS, x1); glPixelStorei(GL_PACK_SKIP_ROWS, y0); glGetCompressedTextureSubImage(tex, level, x1, y0, 0, w1, h0, numSlices, numSlices * compressedSize, testData); /* upper-left */ glPixelStorei(GL_PACK_SKIP_PIXELS, x0); glPixelStorei(GL_PACK_SKIP_ROWS, y1); glGetCompressedTextureSubImage(tex, level, x0, y1, 0, w0, h1, numSlices, numSlices * compressedSize, testData); /* upper-right */ glPixelStorei(GL_PACK_SKIP_PIXELS, x1); glPixelStorei(GL_PACK_SKIP_ROWS, y1); glGetCompressedTextureSubImage(tex, level, x1, y1, 0, w1, h1, numSlices, numSlices * compressedSize, testData); /* defaults */ glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); /* Should be no GL errors */ if (!piglit_check_gl_error(GL_NO_ERROR)) { pass = false; } /* now compare the images */ for (slice = 0; slice < numSlices; slice++) { int sliceStart = slice * compressedSize; if (memcmp(refData + sliceStart, testData + sliceStart, compressedSize)) { int i; for (i = 0; i < compressedSize; i++) { if (refData[sliceStart + i] != testData[sliceStart + i]) { printf("fail in slice/face %d at offset %d\n", slice, i); printf("expected %d, found %d\n", refData[sliceStart + i], testData[sliceStart + i]); break; } } printf("Failure for %s %s\n", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(intFormat)); pass = false; } } free(texData); free(refData); free(testData); glDeleteTextures(1, &tex); return pass; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglCompressedTexSubImage3D(JNIEnv *__env, jclass clazz, jint target, jint level, jint xoffset, jint yoffset, jint zoffset, jint width, jint height, jint depth, jint format, jint imageSize, jlong dataAddress, jlong __functionAddress) { const GLvoid *data = (const GLvoid *)(intptr_t)dataAddress; glCompressedTexSubImage3DPROC glCompressedTexSubImage3D = (glCompressedTexSubImage3DPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglCompressedTexSubImage3D(JNIEnv *env, jclass clazz, jint target, jint level, jint xoffset, jint yoffset, jint zoffset, jint width, jint height, jint depth, jint format, jint imageSize, jlong data, jlong function_pointer) { const GLvoid *data_address = (const GLvoid *)(intptr_t)data; glCompressedTexSubImage3DPROC glCompressedTexSubImage3D = (glCompressedTexSubImage3DPROC)((intptr_t)function_pointer); glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data_address); }
void gl4es_glCompressedMultiTexSubImage3D(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { text(glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)); }