[GELÖST] [C++] Irrlicht - 2D Bilder und mehr...

Übersicht Andere Dialekte Beginners-Corner

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] [C++] Irrlicht - 2D Bilder und mehr...

BeitragMi, Feb 18, 2015 16:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich möchte mich gerne in Irrlicht einarbeiten und versuche Funktionen aus BlitzMax mit Max2D in etwa in Irrlicht und C++ nachzubilden. So habe ich eine Klasse CAnimImage geschrieben, welche wie folgt aussieht Code: [AUSKLAPPEN]
#include <irrlicht.h>

#define CImage ITexture

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

/**
    class CAnimImage
    Desc.: Diese Klasse unterstützt Bilderstrips, von denen Einzelbilder ausgewählt werden können.
           Die Bilder dürfen nur eine Zeile an Bildern haben!
*/
class CAnimImage
{
private:
    CImage*         Image;
    IVideoDriver*   driver;
    int             Frames;
    u32             FrameWidth;
    bool            IsValid;

public:
    CAnimImage(IVideoDriver* driver, const wchar_t* path, u32 framewidth, int framescount)
    {
        this->driver = driver;
        this->Image = driver->getTexture(path);
        this->Frames = framescount;
        this->FrameWidth = framewidth;
        this->IsValid = (this->Image != 0);
    }

    ~CAnimImage()
    {
    }

    bool getValid()
    {
        return this->IsValid;
    }

    void DrawFrame(s32 PositionX, s32 PositionY, int FrameID = 0)
    {
        if (this->Image == 0)
        {
            this->IsValid = false;
            return;
        }

        dimension2d<u32> ImgSize = this->Image->getOriginalSize();

        if (FrameID < 0 || (FrameID * this->FrameWidth + this->FrameWidth) >= ImgSize.Width)
            return;

        this->driver->draw2DImage(this->Image, position2d<s32>(PositionX, PositionY), rect<s32>(FrameID * FrameWidth, 0, FrameWidth, ImgSize.Height), 0, SColor(255, 255, 255, 255), true);
    }

    void SetMaskColor(int alpha, int red, int green, int blue)
    {
        this->driver->makeColorKeyTexture(this->Image, SColor(alpha, red, green, blue));
    }
};


Zudem gibt es folgende Hilfsfunktionen Code: [AUSKLAPPEN]
inline void SetMaskColor(CAnimImage* img, int alpha, int red, int green, int blue)
{
    if (!img)
        return;

    img->SetMaskColor(alpha, red, green, blue);
}

inline CAnimImage* LoadAnimImage(IVideoDriver* driver, const wchar_t* path, u32 framewidth, int framescount)
{
    return new CAnimImage(driver, path, framewidth, framescount);
}

inline void DrawAnimImage(CAnimImage* Image, s32 PositionX, s32 PositionY, int Frame)
{
    if (!Image)
        return;

    Image->DrawFrame(PositionX, PositionY, Frame);
}


Wider erwarten wird sogar ein Bild gemalt - Jedoch nur, wenn ich als Frame 0 angebe. Möchte ich das nächste Bild im Strip malen (theoretisch mit der FrameID 1), so wird nichts gemalt. Meine Vermutung ist nun, dass die folgenden Zeilen Code: [AUSKLAPPEN]
dimension2d<u32> ImgSize = this->Image->getOriginalSize();

        if (FrameID < 0 || (FrameID * this->FrameWidth) >= ImgSize.Width)
dafür sorgen. Und zwar ist es wahrscheinlich die ImgSize.Width, in der Kappes steht. Die Frage ist nun: Gibt es eine Möglichkeit, die Größe eines Bildes zu bestimmen?

Eine weitere Frage: Ich suche - bisher vergeblich - nach einer Alternative zu WritePixel() aus BlitzMax, gibt es eine solche?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Do, Feb 19, 2015 23:48, insgesamt einmal bearbeitet

Thunder

BeitragMi, Feb 18, 2015 22:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß ja nichts über Irrlicht, aber nur Mal so ne Frage: Du glaubst, dass die ImgSize.Width nicht stimmt? Wieso lässt du es dir nicht Mal ausgeben und sagst uns dann, ob es wirklich daran liegt?

Du hast uns übrigens zwei verschiedene Codes geliefert:
Code: [AUSKLAPPEN]
 if (FrameID < 0 || (FrameID * this->FrameWidth) >= ImgSize.Width)
// sowie
 if (FrameID < 0 || (FrameID * this->FrameWidth + this->FrameWidth) >= ImgSize.Width)


Und es fehlt ein Programmstück mit dem du diese Funktionen aufrufst und testest, das das Fehlverhalten reproduziert. Und das Bild.
 

CO2

ehemals "SirMO"

BeitragDo, Feb 19, 2015 23:52
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Thunder:
Ich hatte den Code upgedatet, da die ursprüngliche Version Code: [AUSKLAPPEN]
 if (FrameID < 0 || (FrameID * this->FrameWidth) >= ImgSize.Width)
den gravierenden Fehler enthielt, dass Werte außerhalb des Bildes liegen können, der richtige Code ist somit Code: [AUSKLAPPEN]
if (FrameID < 0 || (FrameID * this->FrameWidth + this->FrameWidth) >= ImgSize.Width)
Ich entschuldige mich für meine fahrlässigkeit Embarassed

Ein weiterer Fehler meinerseits: ImgSize.Width und ImgSize.Height wurden korrekt berechnet, die Definition von irr::core::rect sieht jedoch vor, dass als Parameter zum einen die obere linke und zum anderen die untere rechte Ecke angegeben werden, nicht wie meine Vermutung war obere linke Ecke, Höhe und Breite Embarassed

Der funktionstüchtige Code sieht also folgendermaßen aus Code: [AUSKLAPPEN]
#include <irrlicht.h>

#define CImage ITexture

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

/**
    class CAnimImage
    Desc.: Diese Klasse unterstützt Bilderstrips, von denen Einzelbilder ausgewählt werden können.
           Die Bilder dürfen nur eine Zeile an Bildern haben!
*/
class CAnimImage
{
private:
    CImage*         Image;
    IVideoDriver*   driver;
    int             Frames;
    u32             FrameWidth;
    bool            IsValid;

public:
    CAnimImage(IVideoDriver* driver, const wchar_t* path, u32 framewidth, int framescount)
    {
        this->driver = driver;
        this->Image = driver->getTexture(path);
        this->Frames = framescount;
        this->FrameWidth = framewidth;
        this->IsValid = (this->Image != 0);
    }

    ~CAnimImage()
    {
    }

public:
    bool getValid()
    {
        return this->IsValid;
    }

    void DrawFrame(s32 PositionX, s32 PositionY, int FrameID = 0)
    {
        if (this->Image == 0)
        {
            this->IsValid = false;
            return;
        }

        dimension2d<u32> ImgSize = this->Image->getOriginalSize();

        if (FrameID < 0 || (FrameID * this->FrameWidth + this->FrameWidth) >= ImgSize.Width)
            return;

        this->driver->draw2DImage(this->Image, position2d<s32>(PositionX, PositionY), rect<s32>(FrameID * FrameWidth, 0, FrameID * FrameWidth + FrameWidth, ImgSize.Height), 0, SColor(255, 255, 255, 255), true);
    }

    void SetMaskColor(int alpha, int red, int green, int blue)
    {
        this->driver->makeColorKeyTexture(this->Image, SColor(alpha, red, green, blue));
    }
};

// ************************************************************************************************
inline void SetMaskColor(CAnimImage* img, int alpha, int red, int green, int blue)
{
    if (!img)
        return;

    img->SetMaskColor(alpha, red, green, blue);
}

// ************************************************************************************************
inline CAnimImage* LoadAnimImage(IrrlichtDevice* Dev, const wchar_t* path, u32 framewidth, int framescount)
{
    return new CAnimImage(Dev->getVideoDriver(), path, framewidth, framescount);
}

// ************************************************************************************************
inline void DrawAnimImage(CAnimImage* Image, s32 PositionX, s32 PositionY, int Frame)
{
    if (!Image)
        return;

    Image->DrawFrame(PositionX, PositionY, Frame);
}


Zum Aufruf: Code: [AUSKLAPPEN]

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

int main(int argc, char** argv)
{
    // IrrlichtDevice* Device = createDevice(EDT_OPENGL, dimension2d<u32>(800, 600), 16, false, false, false);

    CAnimImage* img = LoadAnimImage(device, L"car.bmp", 60, 3);
    img->SetMaskColor(255, 255, 0, 255);

    while(device->run())
    {
        // Device->beginScene(...);

        DrawAnimImage(img, 50, 50, 0);
        DrawAnimImage(img, 150, 50, 1);

        // Device->getSceneManager()->drawAll();
        // Device->endScene();
    }

    return 0;
}


Das Bild dazu user posted image
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Neue Antwort erstellen


Übersicht Andere Dialekte Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group