irrlicht render to texture plus shader get a wrong scene

654 Views Asked by At

I have learned irrlicht tutorial 10(about shader) and tutorial 13(about render to texture). But when I use "render to texture" to produce a texture, and use it to a cube, then shader it,the texture turns upside down. Can you tell me is there anything wrong with my code. How to correct this.

There's my code:

#include <irrlicht.h>

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

IrrlichtDevice * device = 0;
//////////////////////////////////////////////
#define ADD_CUBE
#define ADD_CAMERA
#define ADD_RTT
#define ADD_SCAT
#ifdef ADD_SCAT
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

    virtual void OnSetConstants(video::IMaterialRendererServices* services,
            s32 userData)
    {
        video::IVideoDriver* driver = services->getVideoDriver();

        core::matrix4 proj = driver->getTransform(video::ETS_PROJECTION);
        core::matrix4 view = driver->getTransform(video::ETS_VIEW);
        core::matrix4 world = driver->getTransform(video::ETS_WORLD);

        core::matrix4 mvp = proj * view * world;

        services->setVertexShaderConstant("mWorldViewProj", mvp.pointer(), 16);
        s32 TextureLayerID = 0;
        services->setPixelShaderConstant("textureUnit0", &TextureLayerID, 1);
    }
};
#endif

int main()
{
    video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
    u32 shadowDimen = 512;

    device = createDevice(driverType, core::dimension2d<u32>(800, 400), 32);

    scene::ISceneManager * smgr = device->getSceneManager();
    video::IVideoDriver * driver = device->getVideoDriver();


    ////////////////////////////////////////////////////////////////
#ifdef ADD_RTT
    video::ITexture * rt = 0;
    if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET)){
        rt = driver->addRenderTargetTexture(core::dimension2d<u32>(512,512), "RTT1");
    }
#endif
#ifdef ADD_CUBE
    scene::IMeshSceneNode * cubeNode = smgr->addCubeSceneNode(30, 0, -1,
        core::vector3df(0.0, 0.0, 0.0), core::vector3df(0.0, 0.0, 0.0), core::vector3df(4.0, 2.0, 1.0));
    cubeNode->setMaterialFlag(video::EMF_LIGHTING, false);
    cubeNode->setMaterialTexture(0, driver->getTexture("../media/floor.jpg"));
#ifdef ADD_RTT
    scene::IMeshSceneNode * cubeNode2 = smgr->addCubeSceneNode(30, 0, -1,
        core::vector3df(0.0, 0.0, 0.0), core::vector3df(0.0, 0.0, 0.0), core::vector3df(4.0, 2.0, 1.0));
    cubeNode2->setPosition(core::vector3df(0.0, 10.0, 0.0));
    cubeNode2->setMaterialFlag(video::EMF_LIGHTING, false);
    cubeNode2->setMaterialTexture(0, rt);
#endif

#endif
#ifdef ADD_SCAT
    io::path vsFileName = "../media/opengl.vert";
    io::path psFileName = "../media/opengl.frag";
    video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
    s32 newMaterialType1 = 0;
    if(gpu){
        MyShaderCallBack * mc = new MyShaderCallBack();
        newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
            vsFileName, "vertexMain", video::EVST_VS_1_1, 
            psFileName, "pixelMain", video::EPST_PS_1_1,
            mc, video::EMT_SOLID, 0, video::EGSL_DEFAULT);
    }
    cubeNode2->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
#endif
#ifdef ADD_CAMERA
    scene::ICameraSceneNode * camFPS = smgr->addCameraSceneNodeFPS();
    camFPS->setPosition(core::vector3df(0.0, 10.0, -100.0));
    camFPS->setTarget(core::vector3df(0.0, 0.0, 0.0));
#endif
    ////////////////////////////////////////////////////////////////

    int lastFPS = -1;

    while(device->run()){
        if(device->isWindowActive()){
            driver->beginScene(true, true, video::SColor(255, 100, 100, 100));
#ifdef ADD_RTT
            if(rt){
                driver->setRenderTarget(rt, true, true, video::SColor(255, 100, 100, 100));
                cubeNode->setVisible(true);
                cubeNode2->setVisible(false);
                smgr->drawAll();
                driver->setRenderTarget(0, true, true, video::SColor(64, 64, 64, 64));
            }
            cubeNode->setVisible(false);
            cubeNode2->setVisible(true);
#endif
            smgr->drawAll();
            driver->endScene();
        }
        int fps = driver->getFPS();

        int lastFPS = -1;

        if (lastFPS != fps)
        {
            core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;

            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
}



//opengl.vert
//
////uniform mat4 mWorldViewProj;
//void main(void)
//{
//  gl_TexCoord[0] = gl_MultiTexCoord0;
//  gl_Position = mWorldViewProj * gl_Vertex;
//}
//
//
////opengl.frag
//uniform sampler2D textureUnit0;
//void main(void)
//{
//  vec4 color = texture(textureUnit0, gl_TexCoord[0]);
//  gl_FragColor = color;
//}

you can chose any picture.

1

There are 1 best solutions below

0
On

The shader's callback looks good. Try this line in your pixel shader

vec4 color = texture2D(textureUnit0, gl_TexCoord[0].xy);