Page 1 of 1

Is possible to modify the alpha value of a texture?

Posted: Fri Mar 26, 2010 9:23 am
by Tranen
My aim is to change the color of an object in a given amout of time, so I think that a possible way is to applying a texture of a given color and rainsing or lowering the alpha value of the pixels.

This is correct/possible? What is the best way to do this?

Thanks
Tranen

Posted: Fri Mar 26, 2010 9:48 am
by hybrid
There are several ways. It usually depends on how much time you have to spend, and how much you can spend without slowing down our app. With TRANSPARENT_ALPHA_CHANNEL you would have to change the alpha value of each pixel. Moreover, you have to copy the texture to the GPU after it was altered. With VERTEX_ALPHA, you only have to change the vertex color, which can be significantly less work. But you have to copy the full mesh to the GPU again. Finally, with shaders you could set just one parameter to define the overall transparency. Since Irrlicht does not provide such a transparence flag, you need to provide shader materials, though.

Posted: Fri Mar 26, 2010 11:48 am
by Tranen
Hi hybrid thanks for the answer,
since I'm new I don't want to use shader, I think that the better way maybe is to modify the alpha value of the pixel...

The problem is that i don't know how to do this, in the api doc I see that there are some function on the IImage class:

setPixel (u32 x, u32 y, const SColor &color, bool blend=false)=0

but I don't find something similar on the ITexture class..

Could you please explain or tell me in which part of the api doc I should look?

Thanks a lot for your patience.
Tranen

Posted: Fri Mar 26, 2010 1:00 pm
by sudi
Example app:

Header:

Code: Select all

#ifndef APP_H
#define APP_H

#include <irrlicht.h>

class App : irr::IEventReceiver
{
    public:
        /** Default constructor */
        App();
        /** Default destructor */
        virtual ~App();

        void run(void);

        bool OnEvent(const irr::SEvent& event);
    protected:
        irr::IrrlichtDevice* Device;
        irr::gui::IGUIEnvironment* Gui;
        irr::scene::ISceneManager* Smgr;
        irr::video::IVideoDriver* Driver;
        bool RunApp;

        irr::scene::IAnimatedMeshSceneNode* Node;
        irr::s32 ShaderMaterialType;
    private:
};

class MyShaderCallBack : public irr::video::IShaderConstantSetCallBack
{
public:
        void OnSetMaterial(const irr::video::SMaterial& material)
        {
            CurrentMaterial = material;
        }

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

                irr::u32 tex[] = {0,1,2,3};
                services->setVertexShaderConstant("Texture0", (irr::f32*)&tex[0], 1);

                services->setVertexShaderConstant("MaterialTypeParam", &CurrentMaterial.MaterialTypeParam, 1);
                services->setVertexShaderConstant("MaterialTypeParam2", &CurrentMaterial.MaterialTypeParam2, 1);
        }
        irr::video::SMaterial CurrentMaterial;
};


#endif // APP_H
Source:

Code: Select all

#include "App.h"

irr::core::stringc Vertex = "void main()"
                            "{"
                            "   gl_Position = ftransform();"
                            "   gl_TexCoord[0] = gl_MultiTexCoord0;"
                            "}";
irr::core::stringc Fragment = ""
                            "uniform sampler2D Texture0;"
                            "uniform float MaterialTypeParam;"
                            "uniform float MaterialTypeParam2;"
                            "void main()"
                            "{"
                            "   vec4 color = texture2D( Texture0, gl_TexCoord[0].xy );"
                            "   color.a = 1.0-MaterialTypeParam2;"
                            "   gl_FragColor = color;"
                            "}";

App::App()
{
    Device  = irr::createDevice(irr::video::EDT_OPENGL);
    Gui     = Device->getGUIEnvironment();
    Smgr    = Device->getSceneManager();
    Driver  = Device->getVideoDriver();

    Device->setEventReceiver(this);
    RunApp = true;

    Node = 0;

    Smgr->addCameraSceneNode(0, irr::core::vector3df(20,20,20), irr::core::vector3df(0,0,0));

    irr::video::IGPUProgrammingServices* gpu = Driver->getGPUProgrammingServices();

    ShaderMaterialType = gpu->addHighLevelShaderMaterial(
                                Vertex.c_str(), "main", irr::video::EVST_VS_1_1,
                                Fragment.c_str(), "main", irr::video::EPST_PS_1_1,
                                new MyShaderCallBack, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL);

    irr::gui::IGUIScrollBar* bar = Gui->addScrollBar(true, irr::core::rect<irr::s32>(10,10,210,30), 0, 222);
    bar->setMin(0);
    bar->setMax(100);
    bar->setSmallStep(1);

    Gui->addStaticText(L"Press 'L' to load a model and 'ESC' to exit", irr::core::rect<irr::s32>(10,40,210,50));

}

App::~App()
{
    Device->closeDevice();
    Device->drop();
}

bool App::OnEvent(const irr::SEvent& event)
{
    //exit prog
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
    {
        if (event.KeyInput.Key == irr::KEY_ESCAPE)
        {
            RunApp = false;
            return true;
        }
        else if (event.KeyInput.Key == irr::KEY_KEY_L && event.KeyInput.PressedDown)
        {
            Gui->addFileOpenDialog(L"Load mesh", true, 0, 111);
            return true;
        }
    }
    else if (event.EventType == irr::EET_GUI_EVENT)
    {
        if (event.GUIEvent.EventType == irr::gui::EGET_FILE_SELECTED)
        {
            irr::gui::IGUIFileOpenDialog* dialog = (irr::gui::IGUIFileOpenDialog*)event.GUIEvent.Caller;
            if (Node)
            {
                Node->remove();
                Node->drop();
            }
            Node = Smgr->addAnimatedMeshSceneNode(Smgr->getMesh(irr::core::stringc(dialog->getFileName()).c_str()));
            if (Node)
            {
                Node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
                Node->setMaterialType((irr::video::E_MATERIAL_TYPE)ShaderMaterialType);
                Node->grab();
            }
            return true;
        }
        else if (event.GUIEvent.EventType == irr::gui::EGET_SCROLL_BAR_CHANGED)
        {
            if (event.GUIEvent.Caller->getID() == 222) //Alpha bar
            {
                irr::gui::IGUIScrollBar* bar = (irr::gui::IGUIScrollBar*)event.GUIEvent.Caller;
                if (Node)
                {
                    printf("change alpha: %f\n", bar->getPos()/100.0f);
                    for (irr::u32 i= 0;i<Node->getMaterialCount();++i)
                        Node->getMaterial(i).MaterialTypeParam2 = bar->getPos()/100.0f;
                }
            }
        }
    }
    else if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
    {
        if (event.MouseInput.Event == irr::EMIE_MOUSE_WHEEL)
        {
            if (Node)
                Node->setScale(Node->getScale()+irr::core::vector3df(event.MouseInput.Wheel/10.f));
        }
    }
    return false;
}

void App::run(void)
{
    while(Device->run() && RunApp)
    {
        Driver->beginScene(true, true, irr::video::SColor(255,128,128,128));
        Smgr->drawAll();
        Gui->drawAll();
        Driver->endScene();
    }
}

int main(int argc, char* argv[])
{
    App a;
    a.run();
    return 0;
}
Image