Add Texture Array to Current trunk [r5304]

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
JFT90
Posts: 22
Joined: Sun Jan 03, 2016 6:53 pm

Add Texture Array to Current trunk [r5304]

Post 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.
Irrlicht with bgfx-Driver https://gitlab.com/JFT/Irrlicht_extended (forked from Irrlicht trunk)
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Add Texture Array to Current trunk [r5304]

Post 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
Cube_
Posts: 1010
Joined: Mon Oct 24, 2011 10:03 pm
Location: 0x45 61 72 74 68 2c 20 69 6e 20 74 68 65 20 73 6f 6c 20 73 79 73 74 65 6d

Re: Add Texture Array to Current trunk [r5304]

Post 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)
"this is not the bottleneck you are looking for"
Post Reply