Normalmaps look rubbish

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.
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: Normalmaps look rubbish

Post by Asimov »

Hi juanpro,

This is really wierd, I mean really wierd and I hope I can explain what is happening.

Ok first of all this line does not work node->getMaterial(0).setTexture(1,"data/grenade/maps/grenadenrm.tga");
I get an error ||=== Build: Debug in mytests (compiler: GNU GCC Compiler) ===|
H:\Codeblock_Games\Irrlicht\Tests\03_MyTests\src\LoadMesh.cpp||In member function 'void LoadMesh::loadPiece(irr::scene::ISceneManager*, irr::video::IVideoDriver*, const wchar_t*)':|
H:\Codeblock_Games\Irrlicht\Tests\03_MyTests\src\LoadMesh.cpp|41|error: no matching function for call to 'irr::video::SMaterial::setTexture(int, const char [33])'|
H:\Codeblock_Games\Irrlicht\Tests\03_MyTests\src\LoadMesh.cpp|41|note: candidate is:|
H:\SDKs\irrlicht-1.8.1\irrlicht-1.8.1\include\SMaterial.h|482|note: void irr::video::SMaterial::setTexture(irr::u32, irr::video::ITexture*)|
H:\SDKs\irrlicht-1.8.1\irrlicht-1.8.1\include\SMaterial.h|482|note: no known conversion for argument 2 from 'const char [33]' to 'irr::video::ITexture*'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

So let me now explain my set up.
I have a mesh loading class, as I said before. I have two functions in my meshloading class

I have a function called loadMesh and this is for loading all my meshes, and then I have a function called loadPiece. This function is a little different to load mesh as it loads a mesh and makes a camera also.
Because the line above would not work I added this line instead node->setMaterialTexture(1, driver->getTexture("data/grenade/maps/grenadenrm.tga"));

Now when I added that line to my loadPiece function it didn't really do anything.
When I added the same line to the loadMesh function suddenly the normalmap worked. Which is strange because I am not even calling that function.
Although I say it worked, but it is all deformed.
So then I think perhaps it is because irrlicht is loading the normalmap twice. So I renamed the line of the normalmap in the mtl file so it couldn't load, and then the normalmap wouldn't work at all.

In main I am setting up my class with

Code: Select all

LoadMesh grenade;
Then I run my function

Code: Select all

grenade.loadPiece(smgr,driver,L"data/grenade/grenade.obj");
grenade.nodePosition(21.0f,79.3f,21.0f);
 
notice I haven't run the loadMesh function at all

Then here is my full LoadMesh.cpp file. Notice I have put the line node->setMaterialTexture(1, driver->getTexture("data/grenade/maps/grenadenrm.tga")); in a function which isn't even being run.
And yet it kinda works. Something really wierd is going on here. I hope you understand what I am talking about. I say it kinda works because even though you can plainly see the normalmap in the picture, it is slightly deformed. Almost like it is something LOL. My head is gonna explode.

Code: Select all

#include "LoadMesh.h"
 
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace io;
using namespace gui;
 
LoadMesh::LoadMesh()
{
    //constructor
}
 
void LoadMesh::loadMesh(ISceneManager* smgr,IVideoDriver* driver,const wchar_t* modelname)
{
     mesh = smgr->getMesh(modelname);
    node = smgr->addMeshSceneNode(mesh);
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, true);
        node->setPosition(core::vector3df(0,0,0));
        node->addShadowVolumeSceneNode();
 
 
        node->setMaterialTexture(1, driver->getTexture("data/grenade/maps/grenadenrm.tga"));
 
    }
}
 
void LoadMesh::loadPiece(ISceneManager* smgr,IVideoDriver* driver,const wchar_t* modelname)
{
    mesh = smgr->getMesh(modelname);
    node = smgr->addMeshSceneNode(mesh);
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, true);
        node->setPosition(core::vector3df(0,0,0));
        node->addShadowVolumeSceneNode();
 
        node->setRotation(vector3df(-50,0,0));
        camera = smgr->addCameraSceneNode(node,vector3df(0, 5, 5));
        camera->bindTargetAndRotation(true);
        camera->setTarget(node->getPosition());
 
    }
}
 
void zoomCamera(ISceneManager* smgr)
{
//    smgr->setActiveCamera(camera);
}
 
void LoadMesh::RotateMesh(float *rotation,const irr::f32 frameDeltaTime)
{
   //  *rotation-=50 * frameDeltaTime;
     node->setRotation(core::vector3df(0,*rotation,0));
}
 
void LoadMesh::nodePosition(float x,float y,float z)
{
    node->setPosition(vector3df(x,y,z));
}
 
Image
juanjpro
Posts: 12
Joined: Mon Nov 24, 2014 12:54 pm

Re: Normalmaps look rubbish

Post by juanjpro »

Looks like we're getting somewhere. Are you sure that loadMesh isn't being called? That line you added should work for loadPiece.

Also, there should be a diffuse texture (you can use a solid white texture so you can focus on the normal map) or you'll probably get garbage for texture 0, that happened while I was trying to figure out how to set up the textures for my own project. Maybe that's causing the distorted look.
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: Normalmaps look rubbish

Post by Asimov »

Hi juanjpro,

Heh heh I am at me wits end. I want to get more of the programming done, and I have spent 3 days trying to get a normalmap to work.
I have even gone back into 3ds max, and tried changing settings in the exporter, but nothing seems to make it work.
By the way there are bits in this code I am testing eg, the Demo Text. Still haven't worked out how to move it yet LOL.

I am only spending so long on the normalmaps because I can't do much about laying out the game yet, as I have to redesign the board. Going to do it in illustrator at a higher resolution.
However I am finding it difficult to find accurate measurements, and so I have ordered the real boardgame off ebay, as soon as that comes I can build an accurate board.
Most of the board images online are either too low resolution or in American LOL, and I am doing English Monopoly. Going to call it Tomopoly though, 'cause my name is Thomas heh heh.

I will post my main.cpp here
I am definately not loading the grenade into the class twice.

Code: Select all

#pragma once
#ifdef _MSC_VER
// We'll also define this to stop MSVC complaining about sprintf().
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <iostream>
#include "irrlicht.h"
 
 
#include "MyEventReceiver.h"
#include "LoadMesh.h"
#include "House_Hotel_Manager.h"
#include "Fire.h"
 
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace io;
using namespace gui;
 
 
LoadMesh myscene;
House_Hotel_Manager FBHouses;
LoadMesh grenade;
 
MyEventReceiver receiver;
 
int main()
{
// create device
 
IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(800, 600),32, false, true, false, &receiver);
 
    if(!device) return 1;
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
 
    smgr->setAmbientLight(SColor(255, 180, 180, 180));
 
    ILightSceneNode* mySpotLight = smgr->addLightSceneNode();
    mySpotLight->setPosition(vector3df(0.0f, 145.0f, 0.0f));
    mySpotLight->setRotation(vector3df(-90.0f, 0.0f, 0.0f));
     SLight spotLightData;
    spotLightData.Type = ELT_SPOT;
    spotLightData.OuterCone = 300;
    spotLightData.InnerCone = 100;
    mySpotLight->setLightData(spotLightData);
 
 
myscene.loadMesh(smgr,driver,L"data/room/mon2.obj");
 
FBHouses.LoadHouseNodes(smgr,driver);
FBHouses.FillBoardWithHouses(smgr,driver);
 
 
grenade.loadPiece(smgr,driver,L"data/grenade/grenade.obj");
//grenade.nodePosition(21.0f,79.3f,21.0f);
grenade.nodePosition(0,79.3f,22);
 
 
smgr->addSkyDomeSceneNode(driver->getTexture("data/skydome.jpg"),16,16,1.0f,2.5f);
 
 
//I think for bmp-fonts the most important part is that each character starts with a yellow pixel on top-left and ends with a red pixel on bottom right. You can see this for example in fonthattenschweiler.bmp in the media folder.
IGUIFont* fontBig =guienv->getFont("data/bigfont.png");
ITextSceneNode* nodeText = smgr->addTextSceneNode(fontBig,L"Demo Text",(100,100,100));
//nodeText->setText(L"MyText");
 
 
//cameras
ISceneNode* camTarget =smgr->addEmptySceneNode();
camTarget->setPosition(vector3df(0,70,0));
camTarget->setRotation(core::vector3df(0,0,0));
 
ISceneNode* camTarget2 =smgr->addEmptySceneNode();
camTarget2->setPosition(vector3df(0,70,0));
camTarget2->setRotation(core::vector3df(0,90.0f,0));
 
ICameraSceneNode *camera[2]={0,0};
camera[0] = smgr->addCameraSceneNode(camTarget,vector3df(100, 70, 0));
camera[1] = smgr->addCameraSceneNode(camTarget2,vector3df(0, 35, 30));
//camera[2]->setRotation(vector3df(-90,0,0));
 
camera[1]->setTarget(camTarget2->getPosition());
camera[1]->bindTargetAndRotation(true);
 
camera[0]->setTarget(camTarget->getPosition());
camera[0]->bindTargetAndRotation(true);
smgr->setActiveCamera(camera[0]);
 
//smgr->addCameraSceneNodeFPS();
 
float camrot=0;
float camrot2=90.0f;
 
// In order to do framerate independent movement, we have to know
    // how long it was since the last frame
    u32 then = device->getTimer()->getTime();
    // This is the movemen speed in units per second.
    const f32 MOVEMENT_SPEED = 5.f;
 
s32 lastFPS = -1;
    while(device->run())
    {
        // Work out a frame delta time.
        const u32 now = device->getTimer()->getTime();
        const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
        then = now;
 
//    receiver.Checkkeys(receiver,frameDeltaTime,&rotation);
    if(receiver.IsKeyDown(KEY_KEY_S)) smgr->setActiveCamera(camera[0]);
    if(receiver.IsKeyDown(KEY_KEY_W)) smgr->setActiveCamera(camera[1]);
    if(receiver.IsKeyDown(KEY_KEY_T)) smgr->setActiveCamera(grenade.camera);
//    if (receiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_R)){}
 
 
 
if(receiver.IsKeyDown(KEY_KEY_A))
 {
     camTarget->setRotation(vector3df(0,camrot,0));
     camTarget2->setRotation(vector3df(0,camrot2,0));
camrot+=50.0f * frameDeltaTime;
camrot2+=50.0f * frameDeltaTime;
 
 }
 if(receiver.IsKeyDown(KEY_KEY_D))
 {
     camTarget->setRotation(vector3df(0,camrot,0));
     camTarget2->setRotation(vector3df(0,camrot2,0));
camrot-=50.0f * frameDeltaTime;
camrot2-=50.0f * frameDeltaTime;
 }
 
 
 
 if(receiver.IsKeyDown(KEY_KEY_Z))
 {
 
    vector3df pos = camera[0]->getPosition();
    pos.Z += 100*frameDeltaTime;
    camera[0]->setPosition(pos);
    camera[0]->updateAbsolutePosition();
 }
 if(receiver.IsKeyDown(KEY_KEY_X))
 {
     vector3df pos = camera[0]->getPosition();
    pos.Z -= 100*frameDeltaTime;
    camera[0]->setPosition(pos);
    camera[0]->updateAbsolutePosition();
    camera[1]->setPosition(pos);
    camera[1]->updateAbsolutePosition();
 }
 
 
 
        driver->beginScene(true,true,video::SColor(100,100,100,255));
 
        smgr->drawAll();
        guienv->drawAll();
        driver->endScene();
        s32 fps = driver->getFPS();
        if (lastFPS != fps)
        {
            core::stringw str = L"Tomopoly [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;
            str+= " level=";
 
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
    device->drop();
    return 0;
 
}
 
Asimov
Posts: 246
Joined: Thu Dec 04, 2014 7:41 pm
Contact:

Re: Normalmaps look rubbish

Post by Asimov »

Hi all,

I think I have failed with the normalmap completely.
I think the only answer is to learn shaders.

Can anyone point me to any good shader tutorials relavant to irrlicht.

I really wish irrlicht had as many video tutorials as Unity does.
Post Reply