Page 1 of 1

Add Texture Array to Current trunk [r5304]

Posted: Wed Jun 01, 2016 10:15 am
by JFT90
Hi,

because one of my projects needed Texture Arrays to work, I first tried to apply the codechanges proposed here: http://irrlicht.sourceforge.net/forum/v ... =2&t=46826 to the current version of Irrlichts 1.9 trunk.
But since the codebase changed a lot since 2012 (date of the post) I had to adapt to the new COpenGLCoreTexture.h way of doing things ;)
Right now I got the Texture Arrays working again by changing those parts in the code: (I use c++11 so I had to change parts of the makefile a bit, the whole thing should work on Windows and Linux for OpenGL)

Code: Select all

 
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/CImageLoaderPVR.cpp Irrlicht_extended/source/Irrlicht/CImageLoaderPVR.cpp
--- irrlicht-code-5304-trunk/source/Irrlicht/CImageLoaderPVR.cpp    2016-02-14 21:59:43.000000000 +0100
+++ Irrlicht_extended/source/Irrlicht/CImageLoaderPVR.cpp   2016-06-01 10:45:06.632915688 +0200
@@ -187,7 +187,8 @@
        }
        else if (header.NumSurfaces > 1) // texture array
        {
-           // To-DO
+           imageArray.set_used(header.NumSurfaces);
+           tmpType = ETT_ARRAY;
        }
 
        if (type)
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/CNullDriver.cpp Irrlicht_extended/source/Irrlicht/CNullDriver.cpp
--- irrlicht-code-5304-trunk/source/Irrlicht/CNullDriver.cpp    2016-05-27 21:35:22.000000000 +0200
+++ Irrlicht_extended/source/Irrlicht/CNullDriver.cpp   2016-06-01 10:45:06.636915738 +0200
@@ -516,6 +516,27 @@
 }
 
 
+ITexture* CNullDriver::addTextureArray(const io::path& name,irr::core::array<IImage*> images)
+{
+    if (0 == name.size() ||images.empty() )
+       return nullptr;
+
+    ITexture* t = nullptr;
+
+    if(checkImage(images))
+    {
+        t = createDeviceDependentTextureArray(name,images);
+    }
+
+    if(t)
+    {
+        addTexture(t);
+        t->drop();
+    }
+
+    return t;
+}
+
 //! loads a Texture
 ITexture* CNullDriver::getTexture(const io::path& filename)
 {
@@ -632,6 +653,12 @@
                texture = createDeviceDependentTextureCubemap(hashName.size() ? hashName : file->getFileName(), imageArray);
            }
            break;
+        case ETT_ARRAY:
+            if(imageArray.size()>=2)
+            {
+                texture = createDeviceDependentTextureArray(hashName.size() ? hashName : file->getFileName(),imageArray);
+            }
+            break;
        default:
            _IRR_DEBUG_BREAK_IF(true);
            break;
@@ -696,6 +723,11 @@
    return new SDummyTexture(name, ETT_CUBEMAP);
 }
 
+ITexture* CNullDriver::createDeviceDependentTextureArray(const io::path& name, const core::array<IImage*>& image)
+{
+    return new SDummyTexture(name,ETT_ARRAY);
+}
+
 bool CNullDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
 {
    return false;
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/CNullDriver.h Irrlicht_extended/source/Irrlicht/CNullDriver.h
--- irrlicht-code-5304-trunk/source/Irrlicht/CNullDriver.h  2016-05-27 21:35:22.000000000 +0200
+++ Irrlicht_extended/source/Irrlicht/CNullDriver.h 2016-06-01 10:45:06.636915738 +0200
@@ -102,6 +102,8 @@
        virtual ITexture* addTextureCubemap(const io::path& name, IImage* imagePosX, IImage* imageNegX, IImage* imagePosY,
            IImage* imageNegY, IImage* imagePosZ, IImage* imageNegZ) _IRR_OVERRIDE_;
 
+       virtual ITexture* addTextureArray(const io::path& name,irr::core::array<IImage*> images) _IRR_OVERRIDE_;
+
        virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
            f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
 
@@ -685,6 +687,8 @@
 
        virtual ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array<IImage*>& image);
 
+       virtual ITexture* createDeviceDependentTextureArray(const io::path& name, const core::array<IImage*>& image);
+
        //! checks triangle count and print warning if wrong
        bool checkPrimitiveCount(u32 prmcnt) const;
 
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/COpenGLCoreTexture.h Irrlicht_extended/source/Irrlicht/COpenGLCoreTexture.h
--- irrlicht-code-5304-trunk/source/Irrlicht/COpenGLCoreTexture.h   2016-03-15 01:05:21.000000000 +0100
+++ Irrlicht_extended/source/Irrlicht/COpenGLCoreTexture.h  2016-06-01 10:56:07.056175533 +0200
@@ -51,9 +51,9 @@
    {
        _IRR_DEBUG_BREAK_IF(image.size() == 0)
 
-       const GLenum textureType[2] =
+       const GLenum textureType[3] =
        {
-           GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP
+           GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY
        };
 
        DriverType = Driver->getDriverType();
@@ -105,6 +105,10 @@
        if (HasMipMaps)
            glTexParameteri(TextureType, GL_GENERATE_MIPMAP, (AutoGenerateMipMaps) ? GL_TRUE : GL_FALSE);
 #endif
+        if (TextureType == GL_TEXTURE_2D_ARRAY)
+        {
+            glTexImage3D(TextureType, 0, InternalFormat,Size.Width,Size.Height,(*tmpImage).size(),0,PixelFormat,PixelType,nullptr);
+        }
 
        for (u32 i = 0; i < (*tmpImage).size(); ++i)
            uploadTexture(true, i, 0, (*tmpImage)[i]->getData());
@@ -397,6 +401,11 @@
        return StatesCache;
    }
 
+#ifdef _WIN32
+   PFNGLTEXIMAGE3DPROC glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
+       PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
+#endif
+
 protected:
    ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format)
    {
@@ -526,6 +535,9 @@
                    glTexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
 
                break;
+            case GL_TEXTURE_2D_ARRAY:
+                glTexSubImage3D(tmpTextureType, level,0,0,layer,width,height,1,PixelFormat,PixelType,tmpData);
+                break;
            default:
                break;
            }
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/COpenGLDriver.cpp Irrlicht_extended/source/Irrlicht/COpenGLDriver.cpp
--- irrlicht-code-5304-trunk/source/Irrlicht/COpenGLDriver.cpp  2016-03-15 21:02:57.000000000 +0100
+++ Irrlicht_extended/source/Irrlicht/COpenGLDriver.cpp 2016-06-01 10:45:06.640915789 +0200
@@ -2076,6 +2076,19 @@
    return texture;
 }
 
+//! returns a texture array from textures
+ITexture* COpenGLDriver::createDeviceDependentTextureArray(const io::path& name, const core::array<IImage*> &image)
+{
+   /*if (!queryFeature(EVDF_TEXTURE_ARRAY))
+   {
+       os::Printer::log("Array textures not supported", ELL_ERROR);
+       return 0;
+   }*/
+   COpenGLTexture* texture = new COpenGLTexture(name, image, ETT_ARRAY, this);
+
+   return texture;
+}
+
 //! Sets a material. All 3d drawing functions draw geometry now using this material.
 void COpenGLDriver::setMaterial(const SMaterial& material)
 {
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/COpenGLDriver.h Irrlicht_extended/source/Irrlicht/COpenGLDriver.h
--- irrlicht-code-5304-trunk/source/Irrlicht/COpenGLDriver.h    2016-03-15 01:05:21.000000000 +0100
+++ Irrlicht_extended/source/Irrlicht/COpenGLDriver.h   2016-06-01 11:53:43.946324495 +0200
@@ -407,6 +407,9 @@
 
        virtual ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array<IImage*>& image) _IRR_OVERRIDE_;
 
+       //! returns a texture array from textures
+       virtual ITexture* createDeviceDependentTextureArray(const io::path& name, const core::array<IImage*> &image) _IRR_OVERRIDE_;
+
        //! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
        inline void getGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
        inline void getGLTextureMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
diff -ENwbur irrlicht-code-5304-trunk/source/Irrlicht/Makefile Irrlicht_extended/source/Irrlicht/Makefile
--- irrlicht-code-5304-trunk/source/Irrlicht/Makefile   2015-11-29 21:12:51.000000000 +0100
+++ Irrlicht_extended/source/Irrlicht/Makefile  2016-06-01 10:58:39.345109338 +0200
@@ -63,7 +63,7 @@
 #Compiler flags
 CXXINCS = -I../../include -Izlib -Ijpeglib -Ilibpng
 CPPFLAGS += $(CXXINCS) -DIRRLICHT_EXPORTS=1
-CXXFLAGS += -Wall -pipe -fno-exceptions -fno-rtti -fstrict-aliasing
+CXXFLAGS += -Wall -pipe -fno-exceptions -fno-rtti -fstrict-aliasing -std=c++11 -U__STRICT_ANSI__ 
 ifndef NDEBUG
 CXXFLAGS += -g -D_DEBUG
 else
 
/include files:

Code: Select all

 
diff -ENwbur irrlicht-code-5304-trunk/include/IImage.h Irrlicht_extended/include/IImage.h
--- irrlicht-code-5304-trunk/include/IImage.h   2016-03-10 23:13:04.000000000 +0100
+++ Irrlicht_extended/include/IImage.h  2016-06-01 10:45:06.500914006 +0200
@@ -24,7 +24,9 @@
    ETT_2D,
 
    //! Cubemap texture.
-   ETT_CUBEMAP
+   ETT_CUBEMAP,
+
+   ETT_ARRAY
 };
diff -ENwbur irrlicht-code-5304-trunk/include/IVideoDriver.h Irrlicht_extended/include/IVideoDriver.h
--- irrlicht-code-5304-trunk/include/IVideoDriver.h 2016-05-27 21:35:22.000000000 +0200
+++ Irrlicht_extended/include/IVideoDriver.h    2016-06-01 10:45:06.504914057 +0200
@@ -438,6 +438,14 @@
        virtual ITexture* addTextureCubemap(const io::path& name, IImage* imagePosX, IImage* imageNegX, IImage* imagePosY,
            IImage* imageNegY, IImage* imagePosZ, IImage* imageNegZ) = 0;
 
+        //! Creates a 2D texture Array from loaded IImages.
+        /**
+        \param name A name for the texture. Later calls of getTexture() with this name will return this texture.
+        \param images Array of images to create the texture array
+        \return Pointer to the newly created texture. This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+
+       virtual ITexture* addTextureArray(const io::path& name,irr::core::array<IImage*> images) = 0;
+
        //! Adds a new render target texture to the texture cache.
        /** \param size Size of the texture, in pixels. Width and
        height should be a power of two (e.g. 64, 128, 256, 512, ...)
 
For testing , I used this (just modified the old testcode from hendu)
http://www.filedropper.com/showdownload.php/array

It works fine as long as you only use .png images to create the Texture Array, but when I use .jpg files the ITexture pointer becomes a nullpointer :(
Maybe someone can tell me what I have to change to also support .jpg files.

Re: Add Texture Array to Current trunk [r5304]

Posted: Wed Jun 01, 2016 7:54 pm
by Vectrotek
Cool! Irrlicht needs this in its next release!
I'm not too familiar with the engine itself but this look really good!
Keep going! :P

Re: Add Texture Array to Current trunk [r5304]

Posted: Thu Jun 02, 2016 2:36 am
by Cube_
oh, nice patch. I think I'll borrow that one for myself until then. (it ought to be compatible with the FVF branch and if it isn't then I'll just have to make it compatible)