//----------------------------------------------------------------------- void ILUtil::toOgre(const PixelBox &dst) { if(!dst.isConsecutive()) OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "Destination must currently be consecutive", "ILUtil::ilToOgre" ) ; if(dst.getWidth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_WIDTH )) || dst.getHeight() != static_cast<size_t>(ilGetInteger( IL_IMAGE_HEIGHT )) || dst.getDepth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_DEPTH ))) OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Destination dimensions must equal IL dimension", "ILUtil::ilToOgre" ) ; int ilfmt = ilGetInteger( IL_IMAGE_FORMAT ); int iltp = ilGetInteger( IL_IMAGE_TYPE ); // Check if in-memory format just matches // If yes, we can just copy it and save conversion ILFormat ifmt = OgreFormat2ilFormat( dst.format ); if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp)) { memcpy(dst.data, ilGetData(), ilGetInteger( IL_IMAGE_SIZE_OF_DATA )); return; } // Try if buffer is in a known OGRE format so we can use OGRE its // conversion routines PixelFormat bufFmt = ilFormat2OgreFormat((int)ilfmt, (int)iltp); ifmt = OgreFormat2ilFormat( bufFmt ); if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp)) { // IL format matches another OGRE format PixelBox src(dst.getWidth(), dst.getHeight(), dst.getDepth(), bufFmt, ilGetData()); PixelUtil::bulkPixelConversion(src, dst); return; } // Thee extremely slow method if(iltp == IL_UNSIGNED_BYTE || iltp == IL_BYTE) { ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, (uint8)0x00,(uint8)0x00,(uint8)0x00,(uint8)0xFF); } else if(iltp == IL_FLOAT) { ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, 0.0f,0.0f,0.0f,1.0f); } else if(iltp == IL_SHORT || iltp == IL_UNSIGNED_SHORT) { ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, (uint16)0x0000,(uint16)0x0000,(uint16)0x0000,(uint16)0xFFFF); } else { OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "Cannot convert this DevIL type", "ILUtil::ilToOgre" ) ; } }
//----------------------------------------------------------------------------- void GLES2TextureBuffer::download(const PixelBox &data) { #if 0 || defined(GL_NV_get_tex_image) if(data.getWidth() != getWidth() || data.getHeight() != getHeight() || data.getDepth() != getDepth()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "only download of entire buffer is supported by GL", "GLTextureBuffer::download"); glBindTexture( mTarget, mTextureID ); if(PixelUtil::isCompressed(data.format)) { if(data.format != mFormat || !data.isConsecutive()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Compressed images must be consecutive, in the source format", "GLTextureBuffer::download"); // Data must be consecutive and at beginning of buffer as PixelStorei not allowed // for compressed formate glGetCompressedTexImageNV(mFaceTarget, mLevel, data.data); } else { if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) { // Standard alignment of 4 is not right glPixelStorei(GL_PACK_ALIGNMENT, 1); } // We can only get the entire texture glGetTexImageNV(mFaceTarget, mLevel, GLES2PixelUtil::getGLOriginFormat(data.format), GLES2PixelUtil::getGLOriginDataType(data.format), data.data); // Restore defaults glPixelStorei(GL_PACK_ALIGNMENT, 4); } #else OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Downloading texture buffers is not supported by OpenGL ES", "GLES2TextureBuffer::download"); #endif }
void GLESTextureBuffer::upload(const PixelBox &data, const Image::Box &dest) { glBindTexture(mTarget, mTextureID); GL_CHECK_ERROR; if (PixelUtil::isCompressed(data.format)) { if(data.format != mFormat || !data.isConsecutive()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Compressed images must be consecutive, in the source format", "GLESTextureBuffer::upload"); GLenum format = GLESPixelUtil::getClosestGLInternalFormat(mFormat); // Data must be consecutive and at beginning of buffer as PixelStorei not allowed // for compressed formats if (dest.left == 0 && dest.top == 0) { glCompressedTexImage2D(mFaceTarget, mLevel, format, dest.getWidth(), dest.getHeight(), 0, data.getConsecutiveSize(), data.data); GL_CHECK_ERROR; } else { glCompressedTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), format, data.getConsecutiveSize(), data.data); GL_CHECK_ERROR; } } else if (mSoftwareMipmap) { if (data.getWidth() != data.rowPitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLESTextureBuffer::upload"); } if (data.getHeight() * data.getWidth() != data.slicePitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLESTextureBuffer::upload"); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_CHECK_ERROR; buildMipmaps(data); } else { if(data.getWidth() != data.rowPitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLESTextureBuffer::upload"); } if(data.getHeight()*data.getWidth() != data.slicePitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLESTextureBuffer::upload"); } if ((data.getWidth() * PixelUtil::getNumElemBytes(data.format)) & 3) { // Standard alignment of 4 is not right glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_CHECK_ERROR; } // LogManager::getSingleton().logMessage("GLESTextureBuffer::upload - ID: " + StringConverter::toString(mTextureID) + // " Format: " + PixelUtil::getFormatName(data.format) + // " Origin format: " + StringConverter::toString(GLESPixelUtil::getGLOriginFormat(data.format, 0, ' ', std::ios::hex)) + // " Data type: " + StringConverter::toString(GLESPixelUtil::getGLOriginDataType(data.format, 0, ' ', std::ios::hex)) // ); glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), GLESPixelUtil::getGLOriginFormat(data.format), GLESPixelUtil::getGLOriginDataType(data.format), data.data); GL_CHECK_ERROR; } glPixelStorei(GL_UNPACK_ALIGNMENT, 4); GL_CHECK_ERROR; }
//----------------------------------------------------------------------- void ILUtil::fromOgre(const PixelBox &src) { // ilTexImage http://openil.sourceforge.net/docs/il/f00059.htm ILFormat ifmt = OgreFormat2ilFormat( src.format ); if(src.isConsecutive() && ifmt.isValid()) { // The easy case, the buffer is laid out in memory just like // we want it to be and is in a format DevIL can understand directly // We could even save the copy if DevIL would let us ilTexImage(static_cast<ILuint>(src.getWidth()), static_cast<ILuint>(src.getHeight()), static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels, ifmt.format, ifmt.type, src.data); } else if(ifmt.isValid()) { // The format can be understood directly by DevIL. The only // problem is that ilTexImage expects our image data consecutively // so we cannot use that directly. // Let DevIL allocate the memory for us, and copy the data consecutively // to its memory ilTexImage(static_cast<ILuint>(src.getWidth()), static_cast<ILuint>(src.getHeight()), static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels, ifmt.format, ifmt.type, 0); PixelBox dst(src.getWidth(), src.getHeight(), src.getDepth(), src.format, ilGetData()); PixelUtil::bulkPixelConversion(src, dst); } else { // Here it gets ugly. We're stuck with a pixel format that DevIL // can't do anything with. We will do a bulk pixel conversion and // then feed it to DevIL anyway. The problem is finding the best // format to convert to. // most general format supported by OGRE and DevIL PixelFormat fmt = PixelUtil::hasAlpha(src.format)?PF_FLOAT32_RGBA:PF_FLOAT32_RGB; // Make up a pixel format // We don't have to consider luminance formats as they have // straight conversions to DevIL, just weird permutations of RGBA an LA int depths[4]; PixelUtil::getBitDepths(src.format, depths); // Native endian format with all bit depths<8 can safely and quickly be // converted to 24/32 bit if(PixelUtil::isNativeEndian(src.format) && depths[0]<=8 && depths[1]<=8 && depths[2]<=8 && depths[3]<=8) { if(PixelUtil::hasAlpha(src.format)) { fmt = PF_A8R8G8B8; } else { fmt = PF_R8G8B8; } } // Let DevIL allocate the memory for us, then do the conversion ourselves ifmt = OgreFormat2ilFormat( fmt ); ilTexImage(static_cast<ILuint>(src.getWidth()), static_cast<ILuint>(src.getHeight()), static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels, ifmt.format, ifmt.type, 0); PixelBox dst(src.getWidth(), src.getHeight(), src.getDepth(), fmt, ilGetData()); PixelUtil::bulkPixelConversion(src, dst); } }
void GLES2TextureBuffer::upload(const PixelBox &data, const Image::Box &dest) { OGRE_CHECK_GL_ERROR(glBindTexture(mTarget, mTextureID)); if (PixelUtil::isCompressed(data.format)) { if(data.format != mFormat || !data.isConsecutive()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Compressed images must be consecutive, in the source format", "GLES2TextureBuffer::upload"); GLenum format = GLES2PixelUtil::getClosestGLInternalFormat(mFormat); // Data must be consecutive and at beginning of buffer as PixelStorei not allowed // for compressed formats if (dest.left == 0 && dest.top == 0) { OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(mFaceTarget, mLevel, format, dest.getWidth(), dest.getHeight(), 0, data.getConsecutiveSize(), data.data)); } else { OGRE_CHECK_GL_ERROR(glCompressedTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), format, data.getConsecutiveSize(), data.data)); } } else if (mSoftwareMipmap) { if (data.getWidth() != data.rowPitch) { #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch)); #else OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); #endif } if (data.getHeight() * data.getWidth() != data.slicePitch) { #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth()))); #else OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); #endif } #if OGRE_NO_GLES3_SUPPORT == 0 if(data.left > 0 || data.top > 0 || data.front > 0) OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front)); #endif OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); buildMipmaps(data); } else { if (data.getWidth() != data.rowPitch) { #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch)); #else OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); #endif } if (data.getHeight() * data.getWidth() != data.slicePitch) { #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth()))); #else OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); #endif } #if OGRE_NO_GLES3_SUPPORT == 0 if(data.left > 0 || data.top > 0 || data.front > 0) OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front)); #endif if ((data.getWidth() * PixelUtil::getNumElemBytes(data.format)) & 3) { // Standard alignment of 4 is not right OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); } // LogManager::getSingleton().logMessage("GLES2TextureBuffer::upload - ID: " + StringConverter::toString(mTextureID) + // " Format: " + PixelUtil::getFormatName(data.format) + // " Origin format: " + StringConverter::toString(GLES2PixelUtil::getGLOriginFormat(data.format), 0, std::ios::hex) + // " Data type: " + StringConverter::toString(GLES2PixelUtil::getGLOriginDataType(data.format), 0, ' ', std::ios::hex)); OGRE_CHECK_GL_ERROR(glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), GLES2PixelUtil::getGLOriginFormat(data.format), GLES2PixelUtil::getGLOriginDataType(data.format), data.data)); } #if OGRE_NO_GLES3_SUPPORT == 0 OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0)); OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)); #endif OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); }
void GLES2TextureBuffer::upload(const PixelBox &data, const Image::Box &dest) { glBindTexture(mTarget, mTextureID); GL_CHECK_ERROR; if (PixelUtil::isCompressed(data.format)) { if(data.format != mFormat || !data.isConsecutive()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Compressed images must be consecutive, in the source format", "GLES2TextureBuffer::upload"); GLenum format = GLES2PixelUtil::getClosestGLInternalFormat(mFormat); // Data must be consecutive and at beginning of buffer as PixelStorei not allowed // for compressed formats if (dest.left == 0 && dest.top == 0) { glCompressedTexImage2D(mFaceTarget, mLevel, format, dest.getWidth(), dest.getHeight(), 0, data.getConsecutiveSize(), data.data); GL_CHECK_ERROR; } else { glCompressedTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), format, data.getConsecutiveSize(), data.data); GL_CHECK_ERROR; } } else if (mSoftwareMipmap) { if (data.getWidth() != data.rowPitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); } if (data.getHeight() * data.getWidth() != data.slicePitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_CHECK_ERROR; buildMipmaps(data); } else { if(data.getWidth() != data.rowPitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); } if(data.getHeight()*data.getWidth() != data.slicePitch) { // TODO OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported texture format", "GLES2TextureBuffer::upload"); } if ((data.getWidth() * PixelUtil::getNumElemBytes(data.format)) & 3) { // Standard alignment of 4 is not right glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_CHECK_ERROR; } glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, dest.getWidth(), dest.getHeight(), GLES2PixelUtil::getGLOriginFormat(data.format), GLES2PixelUtil::getGLOriginDataType(data.format), data.data); } if ((mUsage & TU_AUTOMIPMAP) && !mSoftwareMipmap && (mLevel == 0)) { glGenerateMipmap(mFaceTarget); GL_CHECK_ERROR; } glPixelStorei(GL_UNPACK_ALIGNMENT, 4); GL_CHECK_ERROR; }