Войти
IrrlichtФорум

Научился рисовать спрайты под углом

#0
20:53, 11 авг. 2010

До тупизны просто, но если кому надо и лень самому писать вот:

#include <irrlicht.h>
// библиотека для рисования изображений под углом
// пример использования:
//IExtDrawing ExtCtrl;
//ExtCtrl.setDriver(driver);
//ExtCtrl.drawImage(pImage,vector2d<s32>(320,240),60,SColor(255,255,255,255));

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

class IExtDrawing{
  IVideoDriver* driver;
  u32 ScrW,ScrH;
  
  S3DVertex2TCoords vertices[4];
  u16 indexList[6];
  

public:
  void setDriver(IVideoDriver* drv){
    // сохраняем указатель
    driver = drv;
    // определяем размеры окна
    ScrW = driver->getScreenSize().Width;
    ScrH = driver->getScreenSize().Height;
    // порядок вершин
    indexList[0] = 0;
    indexList[1] = 1;
    indexList[2] = 2;
    indexList[3] = 0;
    indexList[4] = 2;
    indexList[5] = 3;

  }
  
  void drawImage(ITexture* srcImg, vector2d<s32> destPos,f64 degrees=0, SColor col = SColor(255,255,255,255)){
    vector2d<f32> corners[4];
    f32 W,H;
    W = (float)srcImg->getOriginalSize().Width;
    H = (float)srcImg->getOriginalSize().Height;
    
    // создаем 4 угла прямоугольника с центром в точке (0,0)
    corners[0].X = -W/2;
    corners[0].Y = H/2;

    corners[1].X = - W/2;
    corners[1].Y = - H/2;

    corners[2].X = W/2;
    corners[2].Y = -H/2;

    corners[3].X = W/2;
    corners[3].Y = H/2;

    
    for (int i = 0; i<4; i++){
      //крутим относительно центра
      corners[i].rotateBy(-degrees);
      // преобразуем координаты
      corners[i].X += (float)destPos.X;
      corners[i].Y += (float)destPos.Y;

      corners[i].X = corners[i].X  *2/ScrW - 1;
      corners[i].Y = -corners[i].Y*2/ScrH +1;
    }
    
    //теперь создаем полигон в 3D координатах
    vertices[0] = S3DVertex2TCoords(corners[0].X,corners[0].Y,0,col,  0,1,  0,0);  //0,1
    vertices[1] = S3DVertex2TCoords(corners[1].X,corners[1].Y,0,col,  0,0,  0,0);  //0,0
    vertices[2] = S3DVertex2TCoords(corners[2].X,corners[2].Y,0,col,  1,0,  0,0);  //1,0
    vertices[3] = S3DVertex2TCoords(corners[3].X,corners[3].Y,0,col,  1,1,  0,0);  //1,1
    
    //материал
    SMaterial M;
    M.setTexture(0,srcImg);
    M.setFlag(EMF_LIGHTING ,false);
  //  M.setFlag(video::EMF_COLOR_MATERIAL,true);
    M.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
    
    // рисуем полигон
    driver->setMaterial(M);
    driver->drawIndexedTriangleList(vertices,4,indexList,2);
  }
};

возможно некорректное отображение изображения с размерами некратными степеням двойки


Прошло более 6 месяцев
#1
14:29, 2 мар. 2011

Отлично)
А как доработать класс чтобы можно было задав core::rect<s32> вырезать спрайт из текстуры и развернуть его?
Или как нибудь внутри класса создать новую "виртуальную" текстуру вырезав из реальной заплатку, а затем натянуть её на полигон?
Если кто-то знает подскажите, пожалуйста)

Прошло более 1 года
#2
17:10, 26 мая 2012

А что значит для 2D Режимов. То есть если я инициализировал 3D режим как то так:

device=createDevice(EDT_OPENGL,dimension2d<u32>(640,480),16,false,true,false,0);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
guienv = device->getGUIEnvironment();
driver->getMaterial2D().TextureLayer[0].BilinearFilter=true;
driver->getMaterial2D().AntiAliasing=EAAM_FULL_BASIC;
smgr->addCameraSceneNode(0,vector3df(0,30,-40),vector3df(x,y,z));


Оно что, разве не будет работать???

Прошло более 1 года
#3
17:04, 20 янв. 2014

saz83
некропост:
работать то будет, в том плане что имеет смысл только для 2D графики.

deathTorn
Так как ты сказал (вырезать заплатку) так и делать, добавить в исходные данные destRect и вперед.

Есть правда косяки в работе: некорректно отображаются изображения с размерами сторон некратными степеням двойки (зависит от железа), да и с флагами материала надо поиграться для задания цвета и альфы, я лично не особо соображаю в таких особенностях.

IrrlichtФорум

Тема в архиве.