custom material renderer <- how to set textures?

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
pyrokar
Posts: 12
Joined: Tue Apr 03, 2007 7:05 am

custom material renderer <- how to set textures?

Post by pyrokar »

Hello everybody

I'm currently writing a custom material renderer implementing the IMaterialRenderer interface.

But my custom material renderer is only useful for me if there is both, a Direct3D version and an OpenGL version and if it does not need to include or edit Irrlicht Sources(!)

I've got a problem to implement the OnSetMaterial method of IMaterialRenderer correctly cause i can't call "setTexture" of the VideoDriver since IVideoDriver has no method called "setTexture", but both CDirect3D9Driver and COpenGLDriver has it with exactly the same function signature.
-> shouldn't setTexture be part of IVideoDriver? Why not?

In IVideoDriver.h it says about writing an own material renderer right bevore addMaterialRenderer():

Code: Select all

//! Adds a new material renderer to the video device.
/** Use this method to extend the VideoDriver with new MaterialTypes. To extend the
engine using this method do the following:
Derive a class from IMaterialRenderer and override the methods you need. For setting the right renderstates, you can try to get a pointer to the real rendering device using IVideoDriver::getExposedVideoData().
The ExposedVideoData doesn't really help me to set Textures for OpenGL.

For example COpenGLShaderMaterialRenderer does it like this:

Code: Select all

void COpenGLShaderMaterialRenderer::OnSetMaterial(...)
{
	Driver->setTexture(3, material.Textures[3]);
	Driver->setTexture(2, material.Textures[2]);
	Driver->setTexture(1, material.Textures[1]);
	Driver->setTexture(0, material.Textures[0]);
        ...
}
The point is that COpenGLShaderMaterialRendere knows about COpenGLDriver while my custom renderer doesn't. It can't access COpenGLDriver::setTexture without including Irrlicht Sources.
So i can't set textures as the comment above tells me to.
-> shouldn't setTexture be part of IVideoDriver? Why not?

And yes, i need all 4 textures for my material renderer to be set.

Any solutions?
Remember: I don't want to edit or include Irrlicht Sources.

Thanks, pyrokar
If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot it becomes the teapot.
Now, water can flow or it can crash. Be water my friend.
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Since a texture is set to polygons and materails contain no polygons you cant set textures in the material class, you would have to apply the textures to a node then apply the material to the node.


In irrlicht materials are just "shading insructions" like make transparent or render with shader rather than materials which contain textures etc.. (often reffered that way in other 3d apps)
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, the OpenGL materials enable and disable the materials themselves, because I could not disable them otherwise. The usual way would be to enable all available textures, and depending on the material disable the wrong layers. But we got usually all layers into the result, even though the texture layer was disabled.
pyrokar
Posts: 12
Joined: Tue Apr 03, 2007 7:05 am

Post by pyrokar »

hybrid wrote:No, the OpenGL materials enable and disable the materials themselves, because I could not disable them otherwise. The usual way would be to enable all available textures, and depending on the material disable the wrong layers. But we got usually all layers into the result, even though the texture layer was disabled.
hello hybird

thanks for you answer.

well, that's why i want to and also need to set textures in OnSetMaterial.
I want to write a custom material renderer that uses NVIDIA Cg.
I first tried to convert the code to low level shader code and load it using
IGPUProgrammingServices::addShaderMaterial(...).
But than i realized that i can't set the shader parameters each frame cause i don't know what name my cg program parameters have in the low level shader program.

So now i want to implement a custom material renderer that works like the OpenGL GLSL / the Direct3D HLSL renderer and uses CgGL / CgD3D9 runtime to actually bind the shaders. And that's no problem, but:
And after taking a look into OpenGL GLSL renderer source i saw that it sets all 4 textures in OnSetMaterial.
hybrid wrote: The usual way would be to enable all available textures
Can you tell me how to do that?

Do you have any ideas for a workaround?

Thanks for your time,
pyrokar
If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot it becomes the teapot.
Now, water can flow or it can crash. Be water my friend.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Check the d3d9 driver for the simple way: It sets the textures in a general material function on each call. This should be done for OpenGL as well, but we'd need to disable unused layers properly.
I'd suggest to put your extension into the library and thus using the internal headers etc.
pyrokar
Posts: 12
Joined: Tue Apr 03, 2007 7:05 am

Post by pyrokar »

hybrid wrote:Check the d3d9 driver for the simple way: It sets the textures in a general material function on each call. This should be done for OpenGL as well, but we'd need to disable unused layers properly.
I'd suggest to put your extension into the library and thus using the internal headers etc.
You're right:

Code: Select all

//! sets a material
void CD3D9Driver::setMaterial(const SMaterial& material)
{
	Material = material;
	for (u32 i=0; i<MaxTextureUnits; ++i)
	{
		setTexture(i, Material.Textures[i]);
                ...
	}
}
I will only implement the Cg Material for Direct3D now since i don't need OpenGL support yet in this stage of my game.
I don't want to go though the hasle to recompile and edit my extension every time a new irrlicht version comes out.
I'll have to think about a way to make it work with OpenGL later when I publish my game on Linux.

I'm really looking forward to you to fix this problem in the next irrlicht version so that people can write custom renderers (easier) =)
I could help you if you like but I guess if you haven't really found a good way to do it yet I won't find one either :/

thanks for you help
pyrokar
If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot it becomes the teapot.
Now, water can flow or it can crash. Be water my friend.
Post Reply