Cylinder with createCylinderMesh has a weird texture.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
MartinVee
Posts: 139
Joined: Tue Aug 02, 2016 3:38 pm
Location: Québec, Canada

Cylinder with createCylinderMesh has a weird texture.

Post by MartinVee »

Hi, I'm new to Irrlicht. I'm trying to evaluate the engine to port existing 2D games, in which we'll add 3D effects.

I'm having a problem with a cylinder generated with createCylinderMesh. The texture seems to be mirrored, and the colors are off. Here's a screenshot of the problem :

Image

Details :
Since we'll be using Irrlicht as a 2D engine, I've setup an ortho projection matrix for the camera, and reset the other views to identity. Then I create a cylinder mesh, on which I apply a simple texture (the word TEST with a transparent background), and I add a rotation animator to the cylinder. As a simple test (and to show what the texture actually looks like), I'm also drawing the texture in 2D on the top left corner.

Here's the code :

Code: Select all

 
#include <windows.h>
#include <irrlicht.h>
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
                       
#ifdef _IRR_WINDOWS_
  #pragma comment(lib, "Irrlicht.lib")
  #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
#define SCREEN_WIDTH (1024)
#define SCREEN_HEIGHT (768)
 
int main(int argc, const char* argv[])
{
  IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<u32>(SCREEN_WIDTH, SCREEN_HEIGHT), 16, false, false, false, eventReceiver);
 
  if(device)
  {
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
 
    const core::dimension2d<u32> screenSize = driver->getScreenSize();
 
    /* Set up the projection matrix to translate 3D's origin coordinates to the top left */
    ICameraSceneNode *cam = (scene::ICameraSceneNode *)smgr->getSceneNodeFromType(scene::ESNT_CAMERA);
 
    if(cam == NULL)
    {
      cam = device->getSceneManager()->addCameraSceneNode(0, irr::core::vector3df(screenSize.Width/2, -((f32)(screenSize.Height/2)), -1), irr::core::vector3df(screenSize.Width / 2, -((f32)(screenSize.Height / 2)), 100));
    }
    matrix4 projectionMatrix;
    projectionMatrix.buildProjectionMatrixOrthoLH(screenSize.Width, screenSize.Height, 0.0f, 1000.0f);
    cam->setProjectionMatrix(projectionMatrix, true);
 
    driver->setTransform(video::ETS_WORLD, core::matrix4());
    driver->setTransform(video::ETS_VIEW, core::matrix4());
 
    video::ITexture* testTexture = driver->getTexture("./Resources/test.png");
 
    driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
    driver->getMaterial2D().AntiAliasing = video::EAAM_FULL_BASIC;
    driver->getMaterial2D().MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
 
    IMesh* cylinderMesh = smgr->getGeometryCreator()->createCylinderMesh(1.0f, //radius
                                                                         1.0f, // length
                                                                         50, // tesselation
                                                                         SColor(255, 100, 100, 100), // color
                                                                         true, // closeTop
                                                                         0.0f // oblique
    );
    ISceneNode* cylinder = smgr->addMeshSceneNode(cylinderMesh,
                                                  0, // parent
                                                  -1, // id
                                                  vector3df(0, 0, 0), // position
                                                  vector3df(0, 0, 90), //rotation
                                                  vector3df(200.0f, 200.0f, 200.0f) // scale
    );
    cylinder->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
    cylinder->setMaterialTexture(0, testTexture);
    cylinder->getMaterial(0).AntiAliasing = video::EAAM_FULL_BASIC;
    cylinder->getMaterial(0).TextureLayer[0].BilinearFilter = false;
 
    cylinder->setMaterialFlag(video::EMF_LIGHTING, false);
    cylinder->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, true);
    cylinder->setMaterialFlag(video::EMF_ANTI_ALIASING, false);
    cylinder->setMaterialFlag(video::EMF_USE_MIP_MAPS, false);
    cylinder->getMaterial(0).getTextureMatrix(0).setTextureScale(10.0f, 1.0f);
    cylinder->setPosition(core::vector3df(300, -250, 600));
 
 
    scene::ISceneNodeAnimator* rotationCylinderAnim = smgr->createRotationAnimator(core::vector3df(0.0f, 0.3f, 0.0f));
    if(rotationCylinderAnim)
    {
      cylinder->addAnimator(rotationCylinderAnim);
      rotationCylinderAnim->drop();
    }
 
 
    while(device->run())
    {
      driver->beginScene(true, true, SColor(255, 0, 0, 0));
 
      smgr->drawAll();
      guienv->drawAll();
 
      driver->enableMaterial2D(true);
      driver->draw2DImage(testTexture, core::position2d<s32>(0, 0), core::rect<s32>(0, 0, testTexture->getSize().Width, testTexture->getSize().Height), 0, video::SColor(255, 255, 255, 255), true);
      driver->enableMaterial2D(false);
 
      driver->endScene();
    }
  }
 
  device->drop();
  delete eventReceiver;
 
  return 0;
}
 
I'm quite new to 3D even though I've an extensive background as a 2D game programmer, but it looks like, if I'm not mistaken, that the texture is drawn on the inside of the cylinder, and I can see it by transparency. I tried positioning the object so I can see inside it, but it doesn't seem to render at all.

My main problem is with the cylinder texture (mirrored, and with colors a bit off), but feel free to point out any other mistakes I've made.

Thanks!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Cylinder with createCylinderMesh has a weird texture.

Post by hendu »

Your texture is faded because the fixed-function pipeline multiplies with the vertex color, and you set your vertex colors to grey.

As for the texture X coords behaving like that, it's a matter of convention really - if you'd like them the other way around, set a negative texture scale or flip them in a shader.
MartinVee
Posts: 139
Joined: Tue Aug 02, 2016 3:38 pm
Location: Québec, Canada

Re: Cylinder with createCylinderMesh has a weird texture.

Post by MartinVee »

Ah, thanks hendu for your quick reply!

I changed the vertex colors to white, and the texture colors are good, now. I wasn't aware the default behaviour was to multiply the colors. Should I make sure to create all vertex white to prevent texture colors from fading? Is there a way to define the default fixed-function pipeline behaviour? What is the best practice?

The negative scale also worked!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Cylinder with createCylinderMesh has a weird texture.

Post by hendu »

If you use a shader, then you're in total control of what happens.
Post Reply