Irrlicht (Cross platform 3d game engine) Client

What would you like to see in Freeciv? Do you have a good idea what should be improved or how?
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

Working on windows, it is harder to make a proper client than I expected (mainly due to the fact that diff doesn't run on windows and I can't figure out how to compile gui-stub). Consequently, I will probably focus on adding features to the demo to test them, and slowly try to integrate them into a proper client. (I made the demo with visual studio)
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
cazfi
Elite
Posts: 3069
Joined: Tue Jan 29, 2013 6:54 pm

Re: Irrlicht (Cross platform 3d game engine) Client

Post by cazfi »

Elefant wrote: Sat Jun 11, 2022 3:21 pm I can't figure out how to compile gui-stub).
On autotools build: --enable-client=stub. Meson side has no support for building gui-stub yet, but it should be fairly simple to add.

I don't think I've ever built gui-stub on Windows, though. I'll test that when I have free slot on my Windows build queue (my Windows build machine is currently quite busy, with 3.0.2 release approaching, and also some bootstrap features needing testing)
cazfi
Elite
Posts: 3069
Joined: Tue Jan 29, 2013 6:54 pm

Re: Irrlicht (Cross platform 3d game engine) Client

Post by cazfi »

You could also take discussion about any development obstacles to the freeciv-dev mailing list: https://www.freelists.org/list/freeciv-dev
cazfi
Elite
Posts: 3069
Joined: Tue Jan 29, 2013 6:54 pm

Re: Irrlicht (Cross platform 3d game engine) Client

Post by cazfi »

I did a small refresh to http://www.freeciv.org/wiki/Msys2_As_De ... nvironment
Maybe you find it useful? (it's not completely accurate with its assumptions, though, e.g., at the current moment it won't work for S3_0)
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

Thanks, but I got a Debian machine to do development on. However, I am having a problem with sqlite, where I have it installed (if I run sqlite3 in the terminal, it gives me a version), but autogen.sh can't find it. Also, do you have any programs that you recommend for development, such as an IDE?
Last edited by Elefant on Mon Jun 13, 2022 11:16 pm, edited 1 time in total.
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
cazfi
Elite
Posts: 3069
Joined: Tue Jan 29, 2013 6:54 pm

Re: Irrlicht (Cross platform 3d game engine) Client

Post by cazfi »

Elefant wrote: Mon Jun 13, 2022 12:02 pm Thanks, but I got a Debian machine to do development on. However, I am having a problem with sqlite, where I have it installed (if I run sqlite3 in the terminal, it gives me a version), but autogen.sh can't find it.
Likely, you have just the runtime package, but not the -dev package (containing headers etc. needed to develop/build anything against it).

In this particular case it would be libsqlite3-dev package.
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

That would be the problem. Thanks.
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

Update: Unfortunately, due to time constraints and other projects I need to get done, this project has fallen to the wayside, and will not be completed in the foreseeable future. I got very little done, so what I have done is worthless as a starting point to someone else. If someone else wants to try making an Irrlicht client, it's probably best to start from scratch.
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

Worked on the demo program a bit. Added map rendering and map camera management. Also made a 3D earth intro image.
Here's the code.

Code: Select all

#include <irrlicht.h>
#include <IGUIButton.h>
#include "driverChoice.h"
#include <IGUIEnvironment.h>
#include <list>
#include <random>
#include <algorithm>
#include <iostream>
#include<tuple>

using namespace irr;
using namespace std;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#include <Windows.h>
#else
#include <unistd.h>
#endif

// Define some values that we'll use to identify individual GUI controls.
enum
{
    GUI_ID_NEW_GAME_BUTTON = 101,
    GUI_ID_LOAD_GAME_BUTTON,
    GUI_ID_LOAD_SCENARIO_BUTTON,
    GUI_ID_NET_GAME_BUTTON,
    GUI_ID_SETTINGS_BUTTON,
    GUI_ID_QUIT_BUTTON,
    GUI_ID_LAUNCH_BUTTON,
    GUI_ID_MENU_BUTTON,
    GUI_ID_SETTINGS_SAVE_BUTTON,
    GUI_ID_DRIVER_BOX
};
int view_window = 0;
//set up settings

struct SAppContext
{
    IrrlichtDevice* device;
    s32             counter;
    IGUIListBox* listbox;
    IGUIListBox* ListboxDriver;
};

std::list<tuple <int, int, int>> map_gen()
{
    int x;
    int y;
    std::list<tuple <int, int, int>> map;
    x = 256;
    y = 128;
    //map = {};
    random_device rd;     // only used once to initialise (seed) engine
    srand(rd());    // random-number engine used
    uniform_int_distribution<int> uni(1,5); // guaranteed unbiased
    for (int tile_y = 1; tile_y <= y; ++tile_y)
    {
        //std::cout << "new Y row" << std::endl;
        for (int tile_x = 1; tile_x <= x; ++tile_x)
        {
            //std::cout << "new X row" << std::endl;
            tuple<int, int, int> tile;
            int max;
            int tile_type;
            max = 5; //set the upper bound to generate the random number
            tile_type = rand()%max;
            tile = make_tuple(tile_x, tile_y, tile_type);
            map.push_back(tile);
        }     
    }
    return map;
}

class MyEventReceiver : public IEventReceiver
{
public:
    MyEventReceiver(SAppContext& context) : Context(context)
    {
        for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }

    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_GUI_EVENT)
        {
            s32 id = event.GUIEvent.Caller->getID();
            IGUIEnvironment* env = Context.device->getGUIEnvironment();
            ISceneManager* smgr = Context.device->getSceneManager();
            IVideoDriver* driver = Context.device->getVideoDriver();

            switch (event.GUIEvent.EventType)
            {
            case EGET_BUTTON_CLICKED:
                switch (id)
                {
                case GUI_ID_QUIT_BUTTON:
                    Context.device->closeDevice();
                    return true;

                case GUI_ID_NEW_GAME_BUTTON:
                {
                    view_window = 1;
                    env->clear();
                    env->addButton(rect<s32>(550, 550, 750, 550 + 32), 0, GUI_ID_LAUNCH_BUTTON,
                        L"Launch!", L"Launch a new game");
                    env->addButton(rect<s32>(300, 550, 500, 550 + 32), 0, GUI_ID_MENU_BUTTON,
                        L"Back", L"Back to main menu");
                }
                return true;

                case GUI_ID_SETTINGS_SAVE_BUTTON:
                {
                    IrrlichtDevice* NullDevice = createDevice(irr::video::EDT_NULL);
                    irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter("client/settings.xml");
                    if (!xwriter)
                        return false;
                    xwriter->writeXMLHeader();
                    xwriter->writeElement(L"client");
                    xwriter->writeLineBreak();
                    xwriter->writeElement(L"video");
                    xwriter->writeLineBreak();
                    if (Context.ListboxDriver->getSelected() == 0)
                    {
                        xwriter->writeElement(L"setting", false, L"driver", L"Software");
                        xwriter->writeLineBreak();
                    }
                    if (Context.ListboxDriver->getSelected() == 1)
                    {
                        xwriter->writeElement(L"setting", false, L"driver", L"OpenGL");
                        xwriter->writeLineBreak();
                    }
                    if (Context.ListboxDriver->getSelected() == 2)
                    {
                        xwriter->writeElement(L"setting", false, L"driver", L"DirectX9");
                        xwriter->writeLineBreak();
                    }
                    if (Context.ListboxDriver->getSelected() == 3)
                    {
                        xwriter->writeElement(L"setting", false, L"driver", L"BurningsVideo");
                        xwriter->writeLineBreak();
                    }
                    xwriter->writeLineBreak();
                    xwriter->writeClosingTag(L"video");
                    xwriter->writeLineBreak();
                    xwriter->writeClosingTag(L"client");
                    xwriter->drop();
                    return true;
                }

                case GUI_ID_MENU_BUTTON:
                {
                    view_window = 0;
                    env->clear();
                    env->addButton(rect<s32>(150, 400, 350, 400 + 32), 0, GUI_ID_NEW_GAME_BUTTON,
                        L"New Game", L"Launch a new game");
                    env->addButton(rect<s32>(150, 440, 350, 440 + 32), 0, GUI_ID_LOAD_GAME_BUTTON,
                        L"Load Game", L"Load a saved game");
                    env->addButton(rect<s32>(150, 480, 350, 480 + 32), 0, GUI_ID_LOAD_SCENARIO_BUTTON,
                        L"Load Scenario", L"Loads a prebuilt map");
                    env->addButton(rect<s32>(450, 400, 650, 400 + 32), 0, GUI_ID_NET_GAME_BUTTON,
                        L"Network Game", L"Join a network game");
                    env->addButton(rect<s32>(450, 440, 650, 440 + 32), 0, GUI_ID_SETTINGS_BUTTON,
                        L"Settings", L"Client Settings");
                    env->addButton(rect<s32>(450, 480, 650, 480 + 32), 0, GUI_ID_QUIT_BUTTON,
                        L"Exit", L"Quit");
                    smgr->clear();
                    ICameraSceneNode* camera = 0;
                    camera = smgr->addCameraSceneNode(0, core::vector3df(0, 0, 50),
                        core::vector3df(0, 0, 0));
                    // create test earth
                    ISceneNode* earth = 0;
                    IAnimatedMesh* earthMesh = smgr->getMesh("client/earth.x");
                    if (earthMesh)
                    {
                        //perform various task with the mesh manipulator
                        scene::IMeshManipulator* manipulator = smgr->getMeshManipulator();

                        // create mesh copy with tangent informations from original earth.x mesh
                        scene::IMesh* tangentSphereMesh =
                            manipulator->createMeshWithTangents(earthMesh->getMesh(0));

                        // scale the mesh by factor 10
                        core::matrix4 m;
                        m.setScale(core::vector3df(20, 20, 20));
                        manipulator->transform(tangentSphereMesh, m);

                        earth = smgr->addMeshSceneNode(tangentSphereMesh);
                        earth->setPosition(core::vector3df(0, 0, 0));

                        earth->setMaterialTexture(0,
                            driver->getTexture("client/earth_intro.jpg"));

                        // load heightmap, create normal map from it and set it
                        /*video::ITexture* earthNormalMap = driver->getTexture("client/earthbump.jpg");
                        if (earthNormalMap)
                        {
                            driver->makeNormalMapTexture(earthNormalMap, 20.0f);
                            earth->setMaterialTexture(1, earthNormalMap);
                            earth->setMaterialType(video::EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA);
                        }
                        if you want a texured earth, uncomment this code.
                        */

                        // adjust material settings
                        earth->setMaterialFlag(video::EMF_FOG_ENABLE, true);

                        // add rotation animator
                        scene::ISceneNodeAnimator* anim =
                            smgr->createRotationAnimator(core::vector3df(0, 0.1f, 0));
                        earth->addAnimator(anim);
                        anim->drop();

                        // drop mesh because we created it with a create.. call.
                        tangentSphereMesh->drop();
                    }

                    // add white light
                    smgr->addLightSceneNode(0, core::vector3df(-50, 0, 25),
                        video::SColorf(1.0f, 1.0f, 1.0f));

                    // set ambient light
                    smgr->setAmbientLight(video::SColor(0, 100, 100, 100));
                }
                return true;

                case GUI_ID_LOAD_SCENARIO_BUTTON:
                {
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a scenario map.", true, 0, -1, true);
                    return true;
                }

                case GUI_ID_NET_GAME_BUTTON:
                {
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;

                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 350 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Network Game");

                    env->addStaticText(L"This Feature doesn't work yet .Please close me",
                        rect<s32>(20, 35, 230, 50),
                        true, // border?
                        false, // wordwrap?
                        window);

                }
                return true;

                case GUI_ID_SETTINGS_BUTTON:
                {
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;

                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 350 + Context.counter, 400 + Context.counter),
                        false, // modal?
                        L"Client Settings");

                    env->addStaticText(L"Please select a driver",
                        rect<s32>(20, 35, 230, 50),
                        true, // border?
                        false, // wordwrap?
                        window);

                    Context.ListboxDriver = env->addListBox(rect<s32>(20, 60, 230, 180), window, GUI_ID_DRIVER_BOX, true);

                    //add all available options to the driver choice listbox
                    Context.ListboxDriver->addItem(L"Software");
                    Context.ListboxDriver->addItem(L"OpenGL");
                    Context.ListboxDriver->addItem(L"Directx 9");
                    Context.ListboxDriver->addItem(L"BurningsVideo");

                    env->addButton(rect<s32>(20, 200, 230, 200 + 32), window, GUI_ID_SETTINGS_SAVE_BUTTON,
                        L"Save", L"Save Settings");
                }
                return true;

                case GUI_ID_LOAD_GAME_BUTTON:
                {
                    //Context.listbox->addItem(L"Load Game");
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a save file.", true, 0, -1, true);
                    return true;
                }

                case GUI_ID_LAUNCH_BUTTON:
                {
                    view_window = 2;
                    env->clear();
                    env->addButton(rect<s32>(550, 550, 750, 550 + 32), 0, GUI_ID_MENU_BUTTON,
                        L"Back", L"Back to main menu");
                    smgr->clear();
                    ICameraSceneNode* camera = smgr->addCameraSceneNode(0, core::vector3df(17, 10, 17),
                        core::vector3df(12.5, 0, 12.5));
                    std::list<tuple <int, int, int>> game_map;
                    game_map = map_gen();
                    for(auto tile : game_map)//tuple<int, int, int> tile = game_map.begin(); tile != game_map.end(); ++tile)
                    {
                        if (get<2>(tile) == 0)
                        {
                                IAnimatedMesh* earthMesh = smgr->getMesh("art/terrain/flat/flat.obj");
                                if (!earthMesh)
                                {
                                    Context.device->drop();
                                    return 1;
                                }
                                IAnimatedMeshSceneNode* earth = smgr->addAnimatedMeshSceneNode(earthMesh);
                                int x = get<0>(tile);
                                int y = get<1>(tile);
                                earth->setPosition(core::vector3df(get<0>(tile), 0, get<1>(tile)));
                                earth->setScale(vector3df(0.5, 0.5, 0.5));
                                earth->setMaterialTexture(0, driver->getTexture("art/terrain/flat/flat.png"));
                                earth->setMaterialFlag(video::EMF_LIGHTING, false);
                                //std::cout << "placed tile type flatland" << std::endl;
                        }
                        if (get<2>(tile) == 1)
                        {
                                IAnimatedMesh* earthMesh = smgr->getMesh("art/terrain/flat/flat.obj");
                                if (!earthMesh)
                                {
                                    Context.device->drop();
                                    return 1;
                                }
                                IAnimatedMeshSceneNode* earth = smgr->addAnimatedMeshSceneNode(earthMesh);
                                earth->setPosition(core::vector3df(get<0>(tile), 0, get<1>(tile)));
                                earth->setScale(vector3df(0.5, 0.5, 0.5));
                                earth->setMaterialTexture(0, driver->getTexture("art/terrain/flat/dunes.png"));
                                earth->setMaterialFlag(video::EMF_LIGHTING, false);
                                //std::cout << "placed tile type dunes" << std::endl;
                        }
                        if (get<2>(tile) == 2)
                        {
                                IAnimatedMesh* earthMesh = smgr->getMesh("art/terrain/hill/hill.obj");
                                if (!earthMesh)
                                {
                                    Context.device->drop();
                                    return 1;
                                }
                                IAnimatedMeshSceneNode* earth = smgr->addAnimatedMeshSceneNode(earthMesh);
                                earth->setPosition(core::vector3df(get<0>(tile), 0, get<1>(tile)));
                                earth->setScale(vector3df(0.5, 0.5, 0.5));
                                earth->setMaterialTexture(0, driver->getTexture("art/terrain/hill/hill.png"));
                                earth->setMaterialFlag(video::EMF_LIGHTING, false);
                                //std::cout << "placed tile type hill" << std::endl;
                        }
                        if (get<2>(tile) == 3)
                        {
                                IAnimatedMesh* earthMesh = smgr->getMesh("art/terrain/mountain/mountain.obj");
                                if (!earthMesh)
                                {
                                    Context.device->drop();
                                    return 1;
                                }
                                IAnimatedMeshSceneNode* earth = smgr->addAnimatedMeshSceneNode(earthMesh);
                                earth->setPosition(core::vector3df(get<0>(tile), 0, get<1>(tile)));
                                earth->setScale(vector3df(0.5, 0.5, 0.5));
                                earth->setMaterialTexture(0, driver->getTexture("art/terrain/mountain/mountain.png"));
                                earth->setMaterialFlag(video::EMF_LIGHTING, false);
                                //std::cout << "placed tile type mountain" << std::endl;
                        }
                        if (get<2>(tile) == 4)
                        {
                                IAnimatedMesh* earthMesh = smgr->getMesh("art/terrain/water/water.obj");
                                if (!earthMesh)
                                {
                                    Context.device->drop();
                                    return 1;
                                }
                                IAnimatedMeshSceneNode* earth = smgr->addAnimatedMeshSceneNode(earthMesh);
                                earth->setPosition(core::vector3df(get<0>(tile), 0, get<1>(tile)));
                                earth->setScale(vector3df(0.5, 0.5, 0.5));
                                earth->setMaterialTexture(0, driver->getTexture("art/terrain/water/water.png"));
                                earth->setMaterialFlag(video::EMF_LIGHTING, false);
                                //std::cout << "placed tile type water" << std::endl;
                        }
                    }
                    //Sleep(10000);
                    return true;
                }


                default:
                    return false;
                
                }
                break;

            case EGET_FILE_SELECTED:
            {
                view_window = 1;
                env->clear();
                env->addButton(rect<s32>(550, 550, 750, 550 + 32), 0, GUI_ID_LAUNCH_BUTTON,
                    L"Launch!", L"Launch a new game");
                env->addButton(rect<s32>(300, 550, 500, 550 + 32), 0, GUI_ID_MENU_BUTTON,
                    L"Back", L"Back to main menu");
                // show the model filename, selected in the file dialog
                //IGUIFileOpenDialog* dialog = (IGUIFileOpenDialog*)event.GUIEvent.Caller;
            }
            break;

            default:
                break;
            }
        }
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

        return false;
    }

    // This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
    
private:
    SAppContext& Context;
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
};

int main()
{
    video::E_DRIVER_TYPE driverType = driverChoiceConsole();
    if (driverType == video::EDT_COUNT)
        return 1;

    // create device

    IrrlichtDevice* device = createDevice(driverType,
        core::dimension2d<u32>(800, 600), 64, false, false, true);

    if (device == 0)
        return 1; // could not create selected driver.

    device->setWindowCaption(L"Irrlicht Engine - Freeciv Client Test");
    //set up enviroment
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* env = device->getGUIEnvironment();
    //load images
    ITexture* bg = driver->getTexture("client/bg.png");
    ITexture* intro = 0;//driver->getTexture("client/intro.png");
    intro = driver->addRenderTargetTexture(core::dimension2d<u32>(510, 300), "IntroRT");
    //set up map rendering
    ITexture* map = 0;
    ICameraSceneNode* camera = 0;
    map = driver->addRenderTargetTexture(core::dimension2d<u32>(700, 400), "RTT1");
    camera = smgr->addCameraSceneNode(0, core::vector3df(0, 0, 50),
        core::vector3df(0, 0, 0));
    //set up fonts
    gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
    gui::IGUIFont* font2 =
        device->getGUIEnvironment()->getFont("client/fonthaettenschweiler.bmp");
    IGUISkin* skin = env->getSkin();
    if (font2)
        skin->setFont(font);
    //set up the main menu buttons
    env->addButton(rect<s32>(150, 400, 350, 400 + 32), 0, GUI_ID_NEW_GAME_BUTTON,
        L"New Game", L"Launch a new game");
    env->addButton(rect<s32>(150, 440, 350, 440 + 32), 0, GUI_ID_LOAD_GAME_BUTTON,
        L"Load Game", L"Load a saved game");
    env->addButton(rect<s32>(150, 480, 350, 480 + 32), 0, GUI_ID_LOAD_SCENARIO_BUTTON,
        L"Load Scenario", L"Loads a prebuilt map");
    env->addButton(rect<s32>(450, 400, 650, 400 + 32), 0, GUI_ID_NET_GAME_BUTTON,
        L"Network Game", L"Join a network game");
    env->addButton(rect<s32>(450, 440, 650, 440 + 32), 0, GUI_ID_SETTINGS_BUTTON,
        L"Settings", L"Client Settings");
    env->addButton(rect<s32>(450, 480, 650, 480 + 32), 0, GUI_ID_QUIT_BUTTON,
        L"Exit", L"Quit");

    // Store the appropriate data in a context structure.
    SAppContext context;
    context.device = device;
    context.counter = 0;

    int lastFPS = 0;

    // Then create the event receiver, giving it that context structure.
    MyEventReceiver receiver(context);

    // And tell the device to use our custom event receiver.
    device->setEventReceiver(&receiver);

    // create test earth
    ISceneNode* earth = 0;
    IAnimatedMesh* earthMesh = smgr->getMesh("client/earth.x");
    if (earthMesh)
    {
        //perform various task with the mesh manipulator
        scene::IMeshManipulator* manipulator = smgr->getMeshManipulator();

        // create mesh copy with tangent informations from original earth.x mesh
        scene::IMesh* tangentSphereMesh =
            manipulator->createMeshWithTangents(earthMesh->getMesh(0));

        // scale the mesh by factor 10
        core::matrix4 m;
        m.setScale(core::vector3df(20, 20, 20));
        manipulator->transform(tangentSphereMesh, m);

        earth = smgr->addMeshSceneNode(tangentSphereMesh);
        earth->setPosition(core::vector3df(0, 0, 0));

        earth->setMaterialTexture(0,
            driver->getTexture("client/earth_intro.jpg"));

        // load heightmap, create normal map from it and set it
        /*video::ITexture* earthNormalMap = driver->getTexture("client/earthbump.jpg");
        if (earthNormalMap)
        {
            driver->makeNormalMapTexture(earthNormalMap, 20.0f);
            earth->setMaterialTexture(1, earthNormalMap);
            earth->setMaterialType(video::EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA);
        }
        if you want a texured earth, uncomment this code.
        */

        // adjust material settings
        earth->setMaterialFlag(video::EMF_FOG_ENABLE, true);

        // add rotation animator
        scene::ISceneNodeAnimator* anim =
            smgr->createRotationAnimator(core::vector3df(0, 0.1f, 0));
        earth->addAnimator(anim);
        anim->drop();

        // drop mesh because we created it with a create.. call.
        tangentSphereMesh->drop();
    }

    // add white light
    smgr->addLightSceneNode(0, core::vector3df(-50, 0, 25),
        video::SColorf(1.0f, 1.0f, 1.0f));

    // set ambient light
    smgr->setAmbientLight(video::SColor(0, 100, 100, 100));

    //set up video quality settings
    driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
    driver->getMaterial2D().AntiAliasing = video::EAAM_FULL_BASIC;
    //set up control settings
    const f32 MOVEMENT_SPEED = 5.f;
    u32 then = device->getTimer()->getTime();

    while (device->run() && driver)
    {
        if (device->isWindowActive())
        {
            u32 time = device->getTimer()->getTime();

            driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
            // draw background
            driver->draw2DImage(bg, core::position2d<s32>(0, 0));
            if (view_window == 0)
            {
                // draw intro image
                //driver->draw2DImage(intro, core::position2d<s32>(145, 50));
                //overwrite intro image with rendered earth
                //set up camera
                driver->setRenderTarget(intro, true, true, SColor(0, 0, 0, 0));
                smgr->setActiveCamera(camera);
                smgr->drawAll();
                driver->setRenderTarget(0, true, true, 0);
                // draw background and map
                driver->draw2DImage(bg, core::position2d<s32>(0, 0));
                driver->draw2DImage(intro, core::position2d<s32>(145, 50));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"Welcome to the experimental Irrlicht engine 3D client for freeciv.",
                        core::rect<s32>(250, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));


            }
            if (view_window == 1)
            {
                // draw background and splash
                driver->draw2DImage(bg, core::position2d<s32>(0, 0));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"This is the new game page.",
                        core::rect<s32>(20, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));

            }
            if (view_window == 2)
            {
                // 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;
                core::vector3df nodePosition = camera->getPosition();
                core::vector3df nodeLookat = camera->getTarget();

                if (receiver.IsKeyDown(irr::KEY_SUBTRACT))
                    nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
                else if (receiver.IsKeyDown(irr::KEY_ADD))
                    nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;

                if (receiver.IsKeyDown(irr::KEY_LEFT))
                {
                    nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;
                    nodeLookat.X += MOVEMENT_SPEED * frameDeltaTime;
                }
                else if (receiver.IsKeyDown(irr::KEY_RIGHT))
                {
                    nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
                    nodeLookat.X -= MOVEMENT_SPEED * frameDeltaTime;
                }


                if (receiver.IsKeyDown(irr::KEY_UP))
                {
                    nodePosition.Z -= MOVEMENT_SPEED * frameDeltaTime;
                    nodeLookat.Z -= MOVEMENT_SPEED * frameDeltaTime;
                }
                else if (receiver.IsKeyDown(irr::KEY_DOWN))
                {
                    nodePosition.Z += MOVEMENT_SPEED * frameDeltaTime;
                    nodeLookat.Z += MOVEMENT_SPEED * frameDeltaTime;
                }

                camera->setPosition(nodePosition);
                camera->setTarget(nodeLookat);
                //render map
                //set up camera
                driver->setRenderTarget(map, true, true, SColor(0, 0, 0, 0));
                smgr->setActiveCamera(camera);
                smgr->drawAll();
                driver->setRenderTarget(0, true, true, 0);
                // draw background and map
                driver->draw2DImage(bg, core::position2d<s32>(0, 0));
                driver->draw2DImage(map, core::position2d<s32>(50, 50));
                //draw buttons
                env->drawAll();

                // draw some other text
                if (font2)
                    font2->draw(L"This is the game page.",
                        core::rect<s32>(20, 20, 650, 80),
                        video::SColor(255, 0, 0, 0));
                int fps = driver->getFPS();

                if (lastFPS != fps)
                {
                    core::stringw str = L"Irrlicht Engine - Freeciv Client Test [";
                    str += driver->getName();
                    str += "] FPS:";
                    str += fps;

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

            }
            driver->endScene();
        }
    }

    device->drop();

    return 0;
}
Attachments
New intro screen
New intro screen
IrrCliCapture9.PNG (664.3 KiB) Viewed 3653 times
IrrCliCapture8.PNG
IrrCliCapture8.PNG (783.3 KiB) Viewed 3653 times
IrrCliCapture7.PNG
IrrCliCapture7.PNG (614.58 KiB) Viewed 3653 times
IrrCliCapture6.PNG
IrrCliCapture6.PNG (532.68 KiB) Viewed 3653 times
IrrCliCapture5.PNG
IrrCliCapture5.PNG (678.12 KiB) Viewed 3653 times
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
Elefant
Hardened
Posts: 212
Joined: Sat May 28, 2022 3:55 am

Re: Irrlicht (Cross platform 3d game engine) Client

Post by Elefant »

And here are the tile models and textures.
Attachments
irrlichtclient.zip
(16.65 KiB) Downloaded 145 times
Civ 3 tileset: viewtopic.php?t=92953
3d Irrlicht desktop client development: viewtopic.php?t=92289&start=20
Post Reply