Problem with more than 4 texture layers - Irrlicht 1.7.1

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
andres
Competition winner
Posts: 78
Joined: Tue Jul 08, 2008 5:18 pm
Location: Guarapuava/Brazil
Contact:

Problem with more than 4 texture layers - Irrlicht 1.7.1

Post by andres »

I've an problem to set more than 4 texture layers. Look what i've done:

1 - Unzip Official Irrlicht 1.7.1 package
2 - Change irrCompileConfig.h to support 8 layers:

Code: Select all

#define _IRR_MATERIAL_MAX_TEXTURES_ 8
3 - run "make" in console.


when i try to set the fourth layer (using GLSL) the mesh is rendered with no texture (just black).


here's my code:

Code: Select all

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

	virtual void OnSetConstants(video::IMaterialRendererServices* services,
			s32 userData)
	{
	    int d[]	= {0, 1, 2, 3, 4};		//Sampler2d IDs
	    services->setPixelShaderConstant("myTexture",(float*)&d[4],1);
	}
};

int main(int argc, char** argv)
{
    IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);

    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();

    ISceneNode* node = smgr->addCubeSceneNode(10);

    MyShaderCallBack* mc = new MyShaderCallBack();

    static s32 material=smgr->getVideoDriver()->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
        "shader.vert", "vertexMain", video::EVST_VS_3_0,
        "shader.frag", "pixelMain", video::EPST_PS_3_0,
        mc, video::EMT_SOLID);

    node->setMaterialTexture(0,driver->getTexture("L0.png"));
    node->setMaterialTexture(1,driver->getTexture("L1.jpg"));
    node->setMaterialTexture(2,driver->getTexture("L2.jpg"));
    node->setMaterialTexture(3,driver->getTexture("L3.jpg"));
    node->setMaterialTexture(4,driver->getTexture("L4.jpg"));

    node->setMaterialFlag(EMF_LIGHTING,false);
    node->setMaterialType((E_MATERIAL_TYPE)material);

    smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

    while(device->run())
    {
        driver->beginScene(true, true, SColor(0,200,200,200));

        smgr->drawAll();
        guienv->drawAll();

        driver->endScene();
    }
    device->drop();

    return 0;
}
GLSL vertex program:

Code: Select all

void main(void)
{
	gl_Position = ftransform();
	gl_TexCoord[0] = gl_MultiTexCoord0;
}
GLSL fragment program:

Code: Select all

uniform sampler2D myTexture;

void main (void)
{
    gl_FragColor = texture2D(myTexture, vec2(gl_TexCoord[0]));
}
Why does not work? there is anything else i need to do before compile irrlicht?

PS: OpenSUSE 11.2 + OpenGL 3.2.0 + GLSL 1.5 on Nvidia 9500M GS.
Prof. Andres Jessé Porfirio
Federal Technological University of Parana (UTFPR)
www.andresjesse.com
http://irrrpgbuilder.sourceforge.net

Image
Viz_Fuerte
Posts: 91
Joined: Sun Oct 19, 2008 5:29 pm
Location: Valencia (Spain)
Contact:

Post by Viz_Fuerte »

This seems have, easy solution.

You have compiled well the Irrlicht and the problem is in the code and the programming of the GLSL.

You can do this the way I was doing, or do it this way, but always stating the textures in the GLSL.

In the code needed something like this:

Code: Select all

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

   virtual void OnSetConstants(video::IMaterialRendererServices* services,
         s32 userData)
   {
       int d[]   = {0, 1, 2, 3, 4};      //Sampler2d IDs
       services->setPixelShaderConstant("myTexture0",(float*)&d[0],1);
       services->setPixelShaderConstant("myTexture1",(float*)&d[1],1);
       services->setPixelShaderConstant("myTexture2",(float*)&d[2],1);
       services->setPixelShaderConstant("myTexture3",(float*)&d[3],1);
       services->setPixelShaderConstant("myTexture4",(float*)&d[4],1);
   }
};
And in the GLSL program:

Code: Select all

uniform sampler2D myTexture0;
uniform sampler2D myTexture1;
uniform sampler2D myTexture2;
uniform sampler2D myTexture3;
uniform sampler2D myTexture4;

void main (void)
{
//Here, we must modify the code to do what you want, multi texture, adder ...

..
..
..
    gl_FragColor = texture2D(myTexture0, vec2(gl_TexCoord[0]));
} 
I hope that this will be of assistance :wink:
andres
Competition winner
Posts: 78
Joined: Tue Jul 08, 2008 5:18 pm
Location: Guarapuava/Brazil
Contact:

Post by andres »

don't work.

apparently the OpenGL driver does not recognize my graphics card texture units limit.

In COpenGLExtensionHandler.h the driver try to get MaxTextureUnits, but in my case result apparent to be 4 (Wrong cause Geforce 9500 has 16 Texture Units). So i've changed the line:

Code: Select all

MaxTextureUnits=static_cast<u8>(num);
setting manually to 8 :

Code: Select all

MaxTextureUnits=8;
I now this is not a good solution, but i think it can be a bug (correct me if i'm wrong) and need to be resolved in irrlicht.
Prof. Andres Jessé Porfirio
Federal Technological University of Parana (UTFPR)
www.andresjesse.com
http://irrrpgbuilder.sourceforge.net

Image
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Interesting, nice find. Unfortunately since it's on Linux it's most likely just a driver bug, I'll have to test it under windows and see.

Moving to Bug Reports.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
bmwop
Posts: 11
Joined: Tue Jul 07, 2009 4:04 pm

Post by bmwop »

I use something like this:

Code: Select all

diff -rupN irrlicht-1.7.1/source/Irrlicht/COpenGLExtensionHandler.cpp irrlicht-1.7.1_patch3/source/Irrlicht/COpenGLExtensionHandler.cpp
--- irrlicht-1.7.1/source/Irrlicht/COpenGLExtensionHandler.cpp  2010-02-14 13:04:58.000000000 +0100
+++ irrlicht-1.7.1_patch3/source/Irrlicht/COpenGLExtensionHandler.cpp 2010-06-11 09:41:42.000000000 +0200
@@ -467,6 +467,9 @@ void COpenGLExtensionHandler::initExtens
    {
        glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num);
        MaxTextureUnits=static_cast<u8>(num);
+        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num);
+        if (MaxTextureUnits<static_cast<u8>(num))
+            MaxTextureUnits=static_cast<u8>(num);
    }
 #endif
    glGetIntegerv(GL_MAX_LIGHTS, &num);
andres
Competition winner
Posts: 78
Joined: Tue Jul 08, 2008 5:18 pm
Location: Guarapuava/Brazil
Contact:

Post by andres »

bmwop wrote:I use something like this:

Code: Select all

diff -rupN irrlicht-1.7.1/source/Irrlicht/COpenGLExtensionHandler.cpp irrlicht-1.7.1_patch3/source/Irrlicht/COpenGLExtensionHandler.cpp
--- irrlicht-1.7.1/source/Irrlicht/COpenGLExtensionHandler.cpp  2010-02-14 13:04:58.000000000 +0100
+++ irrlicht-1.7.1_patch3/source/Irrlicht/COpenGLExtensionHandler.cpp 2010-06-11 09:41:42.000000000 +0200
@@ -467,6 +467,9 @@ void COpenGLExtensionHandler::initExtens
    {
        glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num);
        MaxTextureUnits=static_cast<u8>(num);
+        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num);
+        if (MaxTextureUnits<static_cast<u8>(num))
+            MaxTextureUnits=static_cast<u8>(num);
    }
 #endif
    glGetIntegerv(GL_MAX_LIGHTS, &num);
Thanks, works fine.
Prof. Andres Jessé Porfirio
Federal Technological University of Parana (UTFPR)
www.andresjesse.com
http://irrrpgbuilder.sourceforge.net

Image
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

Everything is ok, Irrlicht use GL_MAX_TEXTURE_UNITS as texture limit in OpenGL. On modern cards GL_MAX_TEXTURE_UNITS is equal 4 or 8. This number is important only for fixed function (glEnable/glDisable, glTexEnv, glGetTexEnv etc.) for programmable pipeline, so OpenGL 2.0+ You should use GL_MAX_TEXTURE_IMAGE_UNITS (for max avaiable textures in fragment shader), GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS (for vertex shader) and GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS (for geometry shader in OGL3.2).
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
wing64
Competition winner
Posts: 242
Joined: Wed Jul 23, 2008 2:35 am
Location: Thailand
Contact:

Post by wing64 »

I founded a problem same you on Geforce 9600 GS (update with lastest driver). Try set _IRR_MATERIAL_MAX_TEXTURES_ is 8 but opengl driver return 4 (used GL_MAX_TEXTURE_UNITS). When i change to GL_MAX_TEXTURE_IMAGE_UNITS_ARB my program will work correctly. This's good to change GL_MAX_TEXTURE_UNITS to GL_MAX_TEXTURE_IMAGE_UNITS_ARB or not ? Please suggestion me...
best regards,
shine5128
Posts: 5
Joined: Sun May 02, 2010 12:14 pm

Post by shine5128 »

wing64
Competition winner
Posts: 242
Joined: Wed Jul 23, 2008 2:35 am
Location: Thailand
Contact:

Post by wing64 »

Thanks, It's clear. :D
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Thanks for the link. This will definitely help to improve the current texture handling in Irrlicht.
Post Reply