123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451 |
- // Copyright (C) 2002-2012 Nikolaus Gebhardt
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- #include "CNullDriver.h"
- #include "os.h"
- #include "CImage.h"
- #include "CAttributes.h"
- #include "IReadFile.h"
- #include "IWriteFile.h"
- #include "IImageLoader.h"
- #include "IImageWriter.h"
- #include "IMaterialRenderer.h"
- #include "IAnimatedMeshSceneNode.h"
- #include "CMeshManipulator.h"
- #include "CColorConverter.h"
- #include "IAttributeExchangingObject.h"
- namespace irr
- {
- namespace video
- {
- //! creates a loader which is able to load windows bitmaps
- IImageLoader* createImageLoaderBMP();
- //! creates a loader which is able to load jpeg images
- IImageLoader* createImageLoaderJPG();
- //! creates a loader which is able to load targa images
- IImageLoader* createImageLoaderTGA();
- //! creates a loader which is able to load psd images
- IImageLoader* createImageLoaderPSD();
- //! creates a loader which is able to load dds images
- IImageLoader* createImageLoaderDDS();
- //! creates a loader which is able to load pcx images
- IImageLoader* createImageLoaderPCX();
- //! creates a loader which is able to load png images
- IImageLoader* createImageLoaderPNG();
- //! creates a loader which is able to load WAL images
- IImageLoader* createImageLoaderWAL();
- //! creates a loader which is able to load halflife images
- IImageLoader* createImageLoaderHalfLife();
- //! creates a loader which is able to load lmp images
- IImageLoader* createImageLoaderLMP();
- //! creates a loader which is able to load ppm/pgm/pbm images
- IImageLoader* createImageLoaderPPM();
- //! creates a loader which is able to load rgb images
- IImageLoader* createImageLoaderRGB();
- //! creates a writer which is able to save bmp images
- IImageWriter* createImageWriterBMP();
- //! creates a writer which is able to save jpg images
- IImageWriter* createImageWriterJPG();
- //! creates a writer which is able to save tga images
- IImageWriter* createImageWriterTGA();
- //! creates a writer which is able to save psd images
- IImageWriter* createImageWriterPSD();
- //! creates a writer which is able to save pcx images
- IImageWriter* createImageWriterPCX();
- //! creates a writer which is able to save png images
- IImageWriter* createImageWriterPNG();
- //! creates a writer which is able to save ppm images
- IImageWriter* createImageWriterPPM();
- //! constructor
- CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
- : FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize),
- PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0),
- OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
- {
- #ifdef _DEBUG
- setDebugName("CNullDriver");
- #endif
- DriverAttributes = new io::CAttributes();
- DriverAttributes->addInt("MaxTextures", _IRR_MATERIAL_MAX_TEXTURES_);
- DriverAttributes->addInt("MaxSupportedTextures", _IRR_MATERIAL_MAX_TEXTURES_);
- DriverAttributes->addInt("MaxLights", getMaximalDynamicLightAmount());
- DriverAttributes->addInt("MaxAnisotropy", 1);
- // DriverAttributes->addInt("MaxUserClipPlanes", 0);
- // DriverAttributes->addInt("MaxAuxBuffers", 0);
- DriverAttributes->addInt("MaxMultipleRenderTargets", 1);
- DriverAttributes->addInt("MaxIndices", -1);
- DriverAttributes->addInt("MaxTextureSize", -1);
- // DriverAttributes->addInt("MaxGeometryVerticesOut", 0);
- // DriverAttributes->addFloat("MaxTextureLODBias", 0.f);
- DriverAttributes->addInt("Version", 1);
- DriverAttributes->setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(2048, 2048));
- // DriverAttributes->addInt("ShaderLanguageVersion", 0);
- // DriverAttributes->addInt("AntiAlias", 0);
- setFog();
- setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
- setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);
- ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(screenSize));
- // create manipulator
- MeshManipulator = new scene::CMeshManipulator();
- if (FileSystem)
- FileSystem->grab();
- // create surface loader
- #ifdef _IRR_COMPILE_WITH_PNG_LOADER_
- SurfaceLoader.push_back(video::createImageLoaderPNG());
- #endif
- #ifdef _IRR_COMPILE_WITH_JPG_LOADER_
- SurfaceLoader.push_back(video::createImageLoaderJPG());
- #endif
- #ifdef _IRR_COMPILE_WITH_BMP_LOADER_
- SurfaceLoader.push_back(video::createImageLoaderBMP());
- #endif
- #ifdef _IRR_COMPILE_WITH_JPG_WRITER_
- SurfaceWriter.push_back(video::createImageWriterJPG());
- #endif
- #ifdef _IRR_COMPILE_WITH_PNG_WRITER_
- SurfaceWriter.push_back(video::createImageWriterPNG());
- #endif
- #ifdef _IRR_COMPILE_WITH_BMP_WRITER_
- SurfaceWriter.push_back(video::createImageWriterBMP());
- #endif
- // set ExposedData to 0
- memset(&ExposedData, 0, sizeof(ExposedData));
- for (u32 i=0; i<video::EVDF_COUNT; ++i)
- FeatureEnabled[i]=true;
- InitMaterial2D.AntiAliasing=video::EAAM_OFF;
- InitMaterial2D.Lighting=false;
- InitMaterial2D.ZWriteEnable=false;
- InitMaterial2D.ZBuffer=video::ECFN_NEVER;
- InitMaterial2D.UseMipMaps=false;
- for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
- {
- InitMaterial2D.TextureLayer[i].BilinearFilter=false;
- InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT;
- InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT;
- }
- OverrideMaterial2D=InitMaterial2D;
- }
- //! destructor
- CNullDriver::~CNullDriver()
- {
- if (DriverAttributes)
- DriverAttributes->drop();
- if (FileSystem)
- FileSystem->drop();
- if (MeshManipulator)
- MeshManipulator->drop();
- deleteAllTextures();
- u32 i;
- for (i=0; i<SurfaceLoader.size(); ++i)
- SurfaceLoader[i]->drop();
- for (i=0; i<SurfaceWriter.size(); ++i)
- SurfaceWriter[i]->drop();
- // delete material renderers
- deleteMaterialRenders();
- // delete hardware mesh buffers
- removeAllHardwareBuffers();
- }
- //! Adds an external surface loader to the engine.
- void CNullDriver::addExternalImageLoader(IImageLoader* loader)
- {
- if (!loader)
- return;
- loader->grab();
- SurfaceLoader.push_back(loader);
- }
- //! Adds an external surface writer to the engine.
- void CNullDriver::addExternalImageWriter(IImageWriter* writer)
- {
- if (!writer)
- return;
- writer->grab();
- SurfaceWriter.push_back(writer);
- }
- //! Retrieve the number of image loaders
- u32 CNullDriver::getImageLoaderCount() const
- {
- return SurfaceLoader.size();
- }
- //! Retrieve the given image loader
- IImageLoader* CNullDriver::getImageLoader(u32 n)
- {
- if (n < SurfaceLoader.size())
- return SurfaceLoader[n];
- return 0;
- }
- //! Retrieve the number of image writers
- u32 CNullDriver::getImageWriterCount() const
- {
- return SurfaceWriter.size();
- }
- //! Retrieve the given image writer
- IImageWriter* CNullDriver::getImageWriter(u32 n)
- {
- if (n < SurfaceWriter.size())
- return SurfaceWriter[n];
- return 0;
- }
- //! deletes all textures
- void CNullDriver::deleteAllTextures()
- {
- // we need to remove previously set textures which might otherwise be kept in the
- // last set material member. Could be optimized to reduce state changes.
- setMaterial(SMaterial());
- for (u32 i=0; i<Textures.size(); ++i)
- Textures[i].Surface->drop();
- Textures.clear();
- }
- //! applications must call this method before performing any rendering. returns false if failed.
- bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
- const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
- {
- core::clearFPUException();
- PrimitivesDrawn = 0;
- return true;
- }
- //! applications must call this method after performing any rendering. returns false if failed.
- bool CNullDriver::endScene()
- {
- FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn);
- updateAllHardwareBuffers();
- updateAllOcclusionQueries();
- return true;
- }
- //! Disable a feature of the driver.
- void CNullDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag)
- {
- FeatureEnabled[feature]=!flag;
- }
- //! queries the features of the driver, returns true if feature is available
- bool CNullDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
- {
- return false;
- }
- //! Get attributes of the actual video driver
- const io::IAttributes& CNullDriver::getDriverAttributes() const
- {
- return *DriverAttributes;
- }
- //! Get attributes of the actual video driver
- io::IAttributes& CNullDriver::getNonConstDriverAttributes()
- {
- return *DriverAttributes;
- }
- //! sets transformation
- void CNullDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
- {
- }
- //! Returns the transformation set by setTransform
- const core::matrix4& CNullDriver::getTransform(E_TRANSFORMATION_STATE state) const
- {
- return TransformationMatrix;
- }
- //! sets a material
- void CNullDriver::setMaterial(const SMaterial& material)
- {
- }
- //! Removes a texture from the texture cache and deletes it, freeing lot of
- //! memory.
- void CNullDriver::removeTexture(ITexture* texture)
- {
- if (!texture)
- return;
- for (u32 i=0; i<Textures.size(); ++i)
- {
- if (Textures[i].Surface == texture)
- {
- texture->drop();
- Textures.erase(i);
- }
- }
- }
- //! Removes all texture from the texture cache and deletes them, freeing lot of
- //! memory.
- void CNullDriver::removeAllTextures()
- {
- setMaterial ( SMaterial() );
- deleteAllTextures();
- }
- //! Returns a texture by index
- ITexture* CNullDriver::getTextureByIndex(u32 i)
- {
- if ( i < Textures.size() )
- return Textures[i].Surface;
- return 0;
- }
- //! Returns amount of textures currently loaded
- u32 CNullDriver::getTextureCount() const
- {
- return Textures.size();
- }
- //! Renames a texture
- void CNullDriver::renameTexture(ITexture* texture, const io::path& newName)
- {
- // we can do a const_cast here safely, the name of the ITexture interface
- // is just readonly to prevent the user changing the texture name without invoking
- // this method, because the textures will need resorting afterwards
- io::SNamedPath& name = const_cast<io::SNamedPath&>(texture->getName());
- name.setPath(newName);
- Textures.sort();
- }
- //! loads a Texture
- ITexture* CNullDriver::getTexture(const io::path& filename)
- {
- // Identify textures by their absolute filenames if possible.
- const io::path absolutePath = FileSystem->getAbsolutePath(filename);
- ITexture* texture = findTexture(absolutePath);
- if (texture)
- return texture;
- // Then try the raw filename, which might be in an Archive
- texture = findTexture(filename);
- if (texture)
- return texture;
- // Now try to open the file using the complete path.
- io::IReadFile* file = FileSystem->createAndOpenFile(absolutePath);
- if (!file)
- {
- // Try to open it using the raw filename.
- file = FileSystem->createAndOpenFile(filename);
- }
- if (file)
- {
- // Re-check name for actual archive names
- texture = findTexture(file->getFileName());
- if (texture)
- {
- file->drop();
- return texture;
- }
- texture = loadTextureFromFile(file);
- file->drop();
- if (texture)
- {
- addTexture(texture);
- texture->drop(); // drop it because we created it, one grab too much
- }
- else
- os::Printer::log("Could not load texture", filename, ELL_ERROR);
- return texture;
- }
- else
- {
- os::Printer::log("Could not open file of texture", filename, ELL_WARNING);
- return 0;
- }
- }
- //! loads a Texture
- ITexture* CNullDriver::getTexture(io::IReadFile* file)
- {
- ITexture* texture = 0;
- if (file)
- {
- texture = findTexture(file->getFileName());
- if (texture)
- return texture;
- texture = loadTextureFromFile(file);
- if (texture)
- {
- addTexture(texture);
- texture->drop(); // drop it because we created it, one grab too much
- }
- if (!texture)
- os::Printer::log("Could not load texture", file->getFileName(), ELL_WARNING);
- }
- return texture;
- }
- //! opens the file and loads it into the surface
- video::ITexture* CNullDriver::loadTextureFromFile(io::IReadFile* file, const io::path& hashName )
- {
- ITexture* texture = 0;
- IImage* image = createImageFromFile(file);
- if (image)
- {
- // create texture from surface
- texture = createDeviceDependentTexture(image, hashName.size() ? hashName : file->getFileName() );
- os::Printer::log("Loaded texture", file->getFileName());
- image->drop();
- }
- return texture;
- }
- //! adds a surface, not loaded or created by the Irrlicht Engine
- void CNullDriver::addTexture(video::ITexture* texture)
- {
- if (texture)
- {
- SSurface s;
- s.Surface = texture;
- texture->grab();
- Textures.push_back(s);
- // the new texture is now at the end of the texture list. when searching for
- // the next new texture, the texture array will be sorted and the index of this texture
- // will be changed. to let the order be more consistent to the user, sort
- // the textures now already although this isn't necessary:
- Textures.sort();
- }
- }
- //! looks if the image is already loaded
- video::ITexture* CNullDriver::findTexture(const io::path& filename)
- {
- SSurface s;
- SDummyTexture dummy(filename);
- s.Surface = &dummy;
- s32 index = Textures.binary_search(s);
- if (index != -1)
- return Textures[index].Surface;
- return 0;
- }
- //! Creates a texture from a loaded IImage.
- ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData)
- {
- if ( 0 == name.size() || !image)
- return 0;
- ITexture* t = createDeviceDependentTexture(image, name, mipmapData);
- if (t)
- {
- addTexture(t);
- t->drop();
- }
- return t;
- }
- //! creates a Texture
- ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size,
- const io::path& name, ECOLOR_FORMAT format)
- {
- if(IImage::isRenderTargetOnlyFormat(format))
- {
- os::Printer::log("Could not create ITexture, format only supported for render target textures.", ELL_WARNING);
- return 0;
- }
- if ( 0 == name.size () )
- return 0;
- IImage* image = new CImage(format, size);
- ITexture* t = createDeviceDependentTexture(image, name);
- image->drop();
- addTexture(t);
- if (t)
- t->drop();
- return t;
- }
- //! returns a device dependent texture from a software surface (IImage)
- //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
- ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
- {
- return new SDummyTexture(name);
- }
- //! set or reset special render targets
- bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
- bool clearZBuffer, SColor color)
- {
- if (ERT_FRAME_BUFFER==target)
- return setRenderTarget(0,clearTarget, clearZBuffer, color);
- else
- return false;
- }
- //! sets a render target
- bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
- bool clearZBuffer, SColor color)
- {
- return false;
- }
- //! Sets multiple render targets
- bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture,
- bool clearBackBuffer, bool clearZBuffer, SColor color)
- {
- return false;
- }
- //! sets a viewport
- void CNullDriver::setViewPort(const core::rect<s32>& area)
- {
- }
- //! gets the area of the current viewport
- const core::rect<s32>& CNullDriver::getViewPort() const
- {
- return ViewPort;
- }
- //! draws a vertex primitive list
- void CNullDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
- {
- if ((iType==EIT_16BIT) && (vertexCount>65536))
- os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur.");
- PrimitivesDrawn += primitiveCount;
- }
- //! draws a vertex primitive list in 2d
- void CNullDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
- {
- if ((iType==EIT_16BIT) && (vertexCount>65536))
- os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur.");
- PrimitivesDrawn += primitiveCount;
- }
- //! Draws a 3d line.
- void CNullDriver::draw3DLine(const core::vector3df& start,
- const core::vector3df& end, SColor color)
- {
- }
- //! Draws a 3d triangle.
- void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color)
- {
- S3DVertex vertices[3];
- vertices[0].Pos=triangle.pointA;
- vertices[0].Color=color;
- vertices[0].Normal=triangle.getNormal().normalize();
- vertices[0].TCoords.set(0.f,0.f);
- vertices[1].Pos=triangle.pointB;
- vertices[1].Color=color;
- vertices[1].Normal=vertices[0].Normal;
- vertices[1].TCoords.set(0.5f,1.f);
- vertices[2].Pos=triangle.pointC;
- vertices[2].Color=color;
- vertices[2].Normal=vertices[0].Normal;
- vertices[2].TCoords.set(1.f,0.f);
- const u16 indexList[] = {0,1,2};
- drawVertexPrimitiveList(vertices, 3, indexList, 1, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
- }
- //! Draws a 3d axis aligned box.
- void CNullDriver::draw3DBox(const core::aabbox3d<f32>& box, SColor color)
- {
- core::vector3df edges[8];
- box.getEdges(edges);
- // TODO: optimize into one big drawIndexPrimitive call.
- draw3DLine(edges[5], edges[1], color);
- draw3DLine(edges[1], edges[3], color);
- draw3DLine(edges[3], edges[7], color);
- draw3DLine(edges[7], edges[5], color);
- draw3DLine(edges[0], edges[2], color);
- draw3DLine(edges[2], edges[6], color);
- draw3DLine(edges[6], edges[4], color);
- draw3DLine(edges[4], edges[0], color);
- draw3DLine(edges[1], edges[0], color);
- draw3DLine(edges[3], edges[2], color);
- draw3DLine(edges[7], edges[6], color);
- draw3DLine(edges[5], edges[4], color);
- }
- //! draws an 2d image
- void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos)
- {
- if (!texture)
- return;
- draw2DImage(texture,destPos, core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(texture->getOriginalSize())));
- }
- //! draws a set of 2d images, using a color and the alpha channel of the
- //! texture if desired. The images are drawn beginning at pos and concatenated
- //! in one line. All drawings are clipped against clipRect (if != 0).
- //! The subtextures are defined by the array of sourceRects and are chosen
- //! by the indices given.
- void CNullDriver::draw2DImageBatch(const video::ITexture* texture,
- const core::position2d<s32>& pos,
- const core::array<core::rect<s32> >& sourceRects,
- const core::array<s32>& indices,
- s32 kerningWidth,
- const core::rect<s32>* clipRect, SColor color,
- bool useAlphaChannelOfTexture)
- {
- core::position2d<s32> target(pos);
- for (u32 i=0; i<indices.size(); ++i)
- {
- draw2DImage(texture, target, sourceRects[indices[i]],
- clipRect, color, useAlphaChannelOfTexture);
- target.X += sourceRects[indices[i]].getWidth();
- target.X += kerningWidth;
- }
- }
- //! draws a set of 2d images, using a color and the alpha channel of the
- //! texture if desired.
- void CNullDriver::draw2DImageBatch(const video::ITexture* texture,
- const core::array<core::position2d<s32> >& positions,
- const core::array<core::rect<s32> >& sourceRects,
- const core::rect<s32>* clipRect,
- SColor color,
- bool useAlphaChannelOfTexture)
- {
- const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
- for (u32 i=0; i<drawCount; ++i)
- {
- draw2DImage(texture, positions[i], sourceRects[i],
- clipRect, color, useAlphaChannelOfTexture);
- }
- }
- //! Draws a part of the texture into the rectangle.
- void CNullDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
- const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
- const video::SColor* const colors, bool useAlphaChannelOfTexture)
- {
- if (destRect.isValid())
- draw2DImage(texture, core::position2d<s32>(destRect.UpperLeftCorner),
- sourceRect, clipRect, colors?colors[0]:video::SColor(0xffffffff),
- useAlphaChannelOfTexture);
- }
- //! Draws a 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
- void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
- const core::rect<s32>& sourceRect,
- const core::rect<s32>* clipRect, SColor color,
- bool useAlphaChannelOfTexture)
- {
- }
- //! Draws the outline of a 2d rectangle
- void CNullDriver::draw2DRectangleOutline(const core::recti& pos, SColor color)
- {
- draw2DLine(pos.UpperLeftCorner, core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), color);
- draw2DLine(core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), pos.LowerRightCorner, color);
- draw2DLine(pos.LowerRightCorner, core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), color);
- draw2DLine(core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), pos.UpperLeftCorner, color);
- }
- //! Draw a 2d rectangle
- void CNullDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, const core::rect<s32>* clip)
- {
- draw2DRectangle(pos, color, color, color, color, clip);
- }
- //! Draws a 2d rectangle with a gradient.
- void CNullDriver::draw2DRectangle(const core::rect<s32>& pos,
- SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
- const core::rect<s32>* clip)
- {
- }
- //! Draws a 2d line.
- void CNullDriver::draw2DLine(const core::position2d<s32>& start,
- const core::position2d<s32>& end, SColor color)
- {
- }
- //! Draws a pixel
- void CNullDriver::drawPixel(u32 x, u32 y, const SColor & color)
- {
- }
- //! Draws a non filled concyclic regular 2d polyon.
- void CNullDriver::draw2DPolygon(core::position2d<s32> center,
- f32 radius, video::SColor color, s32 count)
- {
- if (count < 2)
- return;
- core::position2d<s32> first;
- core::position2d<s32> a,b;
- for (s32 j=0; j<count; ++j)
- {
- b = a;
- f32 p = j / (f32)count * (core::PI*2);
- a = center + core::position2d<s32>((s32)(sin(p)*radius), (s32)(cos(p)*radius));
- if (j==0)
- first = a;
- else
- draw2DLine(a, b, color);
- }
- draw2DLine(a, first, color);
- }
- //! returns color format
- ECOLOR_FORMAT CNullDriver::getColorFormat() const
- {
- return ECF_R5G6B5;
- }
- //! returns screen size
- const core::dimension2d<u32>& CNullDriver::getScreenSize() const
- {
- return ScreenSize;
- }
- //! returns the current render target size,
- //! or the screen size if render targets are not implemented
- const core::dimension2d<u32>& CNullDriver::getCurrentRenderTargetSize() const
- {
- return ScreenSize;
- }
- // returns current frames per second value
- s32 CNullDriver::getFPS() const
- {
- return FPSCounter.getFPS();
- }
- //! returns amount of primitives (mostly triangles) were drawn in the last frame.
- //! very useful method for statistics.
- u32 CNullDriver::getPrimitiveCountDrawn( u32 param ) const
- {
- return (0 == param) ? FPSCounter.getPrimitive() : (1 == param) ? FPSCounter.getPrimitiveAverage() : FPSCounter.getPrimitiveTotal();
- }
- //! Sets the dynamic ambient light color. The default color is
- //! (0,0,0,0) which means it is dark.
- //! \param color: New color of the ambient light.
- void CNullDriver::setAmbientLight(const SColorf& color)
- {
- }
- //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
- //! driver, it would return "Direct3D8".
- const wchar_t* CNullDriver::getName() const
- {
- return L"Irrlicht NullDevice";
- }
- //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
- //! this: Frist, draw all geometry. Then use this method, to draw the shadow
- //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
- void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
- {
- }
- //! Fills the stencil shadow with color. After the shadow volume has been drawn
- //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
- //! to draw the color of the shadow.
- void CNullDriver::drawStencilShadow(bool clearStencilBuffer,
- video::SColor leftUpEdge, video::SColor rightUpEdge,
- video::SColor leftDownEdge, video::SColor rightDownEdge)
- {
- }
- //! deletes all dynamic lights there are
- void CNullDriver::deleteAllDynamicLights()
- {
- Lights.set_used(0);
- }
- //! adds a dynamic light
- s32 CNullDriver::addDynamicLight(const SLight& light)
- {
- Lights.push_back(light);
- return Lights.size() - 1;
- }
- //! Turns a dynamic light on or off
- //! \param lightIndex: the index returned by addDynamicLight
- //! \param turnOn: true to turn the light on, false to turn it off
- void CNullDriver::turnLightOn(s32 lightIndex, bool turnOn)
- {
- // Do nothing
- }
- //! returns the maximal amount of dynamic lights the device can handle
- u32 CNullDriver::getMaximalDynamicLightAmount() const
- {
- return 0;
- }
- //! Returns current amount of dynamic lights set
- //! \return Current amount of dynamic lights set
- u32 CNullDriver::getDynamicLightCount() const
- {
- return Lights.size();
- }
- //! Returns light data which was previously set by IVideoDriver::addDynamicLight().
- //! \param idx: Zero based index of the light. Must be greater than 0 and smaller
- //! than IVideoDriver()::getDynamicLightCount.
- //! \return Light data.
- const SLight& CNullDriver::getDynamicLight(u32 idx) const
- {
- if ( idx < Lights.size() )
- return Lights[idx];
- else
- return *((SLight*)0);
- }
- //! Creates a boolean alpha channel of the texture based of an color key.
- void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
- video::SColor color,
- bool zeroTexels) const
- {
- if (!texture)
- return;
- if (texture->getColorFormat() != ECF_A1R5G5B5 &&
- texture->getColorFormat() != ECF_A8R8G8B8 )
- {
- os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR);
- return;
- }
- if (texture->getColorFormat() == ECF_A1R5G5B5)
- {
- u16 *p = (u16*)texture->lock();
- if (!p)
- {
- os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR);
- return;
- }
- const core::dimension2d<u32> dim = texture->getSize();
- const u32 pitch = texture->getPitch() / 2;
- // color with alpha disabled (i.e. fully transparent)
- const u16 refZeroAlpha = (0x7fff & color.toA1R5G5B5());
- const u32 pixels = pitch * dim.Height;
- for (u32 pixel = 0; pixel < pixels; ++ pixel)
- {
- // If the color matches the reference color, ignoring alphas,
- // set the alpha to zero.
- if(((*p) & 0x7fff) == refZeroAlpha)
- {
- if(zeroTexels)
- (*p) = 0;
- else
- (*p) = refZeroAlpha;
- }
- ++p;
- }
- texture->unlock();
- }
- else
- {
- u32 *p = (u32*)texture->lock();
- if (!p)
- {
- os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR);
- return;
- }
- core::dimension2d<u32> dim = texture->getSize();
- u32 pitch = texture->getPitch() / 4;
- // color with alpha disabled (fully transparent)
- const u32 refZeroAlpha = 0x00ffffff & color.color;
- const u32 pixels = pitch * dim.Height;
- for (u32 pixel = 0; pixel < pixels; ++ pixel)
- {
- // If the color matches the reference color, ignoring alphas,
- // set the alpha to zero.
- if(((*p) & 0x00ffffff) == refZeroAlpha)
- {
- if(zeroTexels)
- (*p) = 0;
- else
- (*p) = refZeroAlpha;
- }
- ++p;
- }
- texture->unlock();
- }
- texture->regenerateMipMapLevels();
- }
- //! Creates an boolean alpha channel of the texture based of an color key position.
- void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
- core::position2d<s32> colorKeyPixelPos,
- bool zeroTexels) const
- {
- if (!texture)
- return;
- if (texture->getColorFormat() != ECF_A1R5G5B5 &&
- texture->getColorFormat() != ECF_A8R8G8B8 )
- {
- os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR);
- return;
- }
- SColor colorKey;
- if (texture->getColorFormat() == ECF_A1R5G5B5)
- {
- u16 *p = (u16*)texture->lock(ETLM_READ_ONLY);
- if (!p)
- {
- os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR);
- return;
- }
- u32 pitch = texture->getPitch() / 2;
- const u16 key16Bit = 0x7fff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X];
- colorKey = video::A1R5G5B5toA8R8G8B8(key16Bit);
- }
- else
- {
- u32 *p = (u32*)texture->lock(ETLM_READ_ONLY);
- if (!p)
- {
- os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR);
- return;
- }
- u32 pitch = texture->getPitch() / 4;
- colorKey = 0x00ffffff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X];
- }
- texture->unlock();
- makeColorKeyTexture(texture, colorKey, zeroTexels);
- }
- //! Creates a normal map from a height map texture.
- //! \param amplitude: Constant value by which the height information is multiplied.
- void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const
- {
- if (!texture)
- return;
- if (texture->getColorFormat() != ECF_A1R5G5B5 &&
- texture->getColorFormat() != ECF_A8R8G8B8 )
- {
- os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR);
- return;
- }
- core::dimension2d<u32> dim = texture->getSize();
- amplitude = amplitude / 255.0f;
- f32 vh = dim.Height / (f32)dim.Width;
- f32 hh = dim.Width / (f32)dim.Height;
- if (texture->getColorFormat() == ECF_A8R8G8B8)
- {
- // ECF_A8R8G8B8 version
- s32 *p = (s32*)texture->lock();
- if (!p)
- {
- os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR);
- return;
- }
- // copy texture
- u32 pitch = texture->getPitch() / 4;
- s32* in = new s32[dim.Height * pitch];
- memcpy(in, p, dim.Height * pitch * 4);
- for (s32 x=0; x < s32(pitch); ++x)
- for (s32 y=0; y < s32(dim.Height); ++y)
- {
- // TODO: this could be optimized really a lot
- core::vector3df h1((x-1)*hh, nml32(x-1, y, pitch, dim.Height, in)*amplitude, y*vh);
- core::vector3df h2((x+1)*hh, nml32(x+1, y, pitch, dim.Height, in)*amplitude, y*vh);
- //core::vector3df v1(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
- //core::vector3df v2(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
- core::vector3df v1(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
- core::vector3df v2(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
- core::vector3df v = v1-v2;
- core::vector3df h = h1-h2;
- core::vector3df n = v.crossProduct(h);
- n.normalize();
- n *= 0.5f;
- n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1
- n *= 255.0f;
- s32 height = (s32)nml32(x, y, pitch, dim.Height, in);
- p[y*pitch + x] = video::SColor(
- height, // store height in alpha
- (s32)n.X, (s32)n.Z, (s32)n.Y).color;
- }
- delete [] in;
- texture->unlock();
- }
- else
- {
- // ECF_A1R5G5B5 version
- s16 *p = (s16*)texture->lock();
- if (!p)
- {
- os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR);
- return;
- }
- u32 pitch = texture->getPitch() / 2;
- // copy texture
- s16* in = new s16[dim.Height * pitch];
- memcpy(in, p, dim.Height * pitch * 2);
- for (s32 x=0; x < s32(pitch); ++x)
- for (s32 y=0; y < s32(dim.Height); ++y)
- {
- // TODO: this could be optimized really a lot
- core::vector3df h1((x-1)*hh, nml16(x-1, y, pitch, dim.Height, in)*amplitude, y*vh);
- core::vector3df h2((x+1)*hh, nml16(x+1, y, pitch, dim.Height, in)*amplitude, y*vh);
- core::vector3df v1(x*hh, nml16(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
- core::vector3df v2(x*hh, nml16(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
- core::vector3df v = v1-v2;
- core::vector3df h = h1-h2;
- core::vector3df n = v.crossProduct(h);
- n.normalize();
- n *= 0.5f;
- n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1
- n *= 255.0f;
- p[y*pitch + x] = video::RGBA16((u32)n.X, (u32)n.Z, (u32)n.Y);
- }
- delete [] in;
- texture->unlock();
- }
- texture->regenerateMipMapLevels();
- }
- //! Returns the maximum amount of primitives (mostly vertices) which
- //! the device is able to render with one drawIndexedTriangleList
- //! call.
- u32 CNullDriver::getMaximalPrimitiveCount() const
- {
- return 0xFFFFFFFF;
- }
- //! checks triangle count and print warning if wrong
- bool CNullDriver::checkPrimitiveCount(u32 prmCount) const
- {
- const u32 m = getMaximalPrimitiveCount();
- if (prmCount > m)
- {
- char tmp[1024];
- sprintf(tmp,"Could not draw triangles, too many primitives(%u), maxium is %u.", prmCount, m);
- os::Printer::log(tmp, ELL_ERROR);
- return false;
- }
- return true;
- }
- //! Enables or disables a texture creation flag.
- void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled)
- {
- if (enabled && ((flag == ETCF_ALWAYS_16_BIT) || (flag == ETCF_ALWAYS_32_BIT)
- || (flag == ETCF_OPTIMIZED_FOR_QUALITY) || (flag == ETCF_OPTIMIZED_FOR_SPEED)))
- {
- // disable other formats
- setTextureCreationFlag(ETCF_ALWAYS_16_BIT, false);
- setTextureCreationFlag(ETCF_ALWAYS_32_BIT, false);
- setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, false);
- setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false);
- }
- // set flag
- TextureCreationFlags = (TextureCreationFlags & (~flag)) |
- ((((u32)!enabled)-1) & flag);
- }
- //! Returns if a texture creation flag is enabled or disabled.
- bool CNullDriver::getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const
- {
- return (TextureCreationFlags & flag)!=0;
- }
- //! Creates a software image from a file.
- IImage* CNullDriver::createImageFromFile(const io::path& filename)
- {
- if (!filename.size())
- return 0;
- IImage* image = 0;
- io::IReadFile* file = FileSystem->createAndOpenFile(filename);
- if (file)
- {
- image = createImageFromFile(file);
- file->drop();
- }
- else
- os::Printer::log("Could not open file of image", filename, ELL_WARNING);
- return image;
- }
- //! Creates a software image from a file.
- IImage* CNullDriver::createImageFromFile(io::IReadFile* file, video::IImageLoader** loader)
- {
- if (!file)
- return 0;
- IImage* image = 0;
- s32 i;
- // try to load file based on file extension
- for (i=SurfaceLoader.size()-1; i>=0; --i)
- {
- if (SurfaceLoader[i]->isALoadableFileExtension(file->getFileName()))
- {
- if (loader)
- {
- *loader = SurfaceLoader[i];
- return 0;
- }
- // reset file position which might have changed due to previous loadImage calls
- file->seek(0);
- image = SurfaceLoader[i]->loadImage(file);
- if (image)
- return image;
- }
- }
- // try to load file based on what is in it
- for (i=SurfaceLoader.size()-1; i>=0; --i)
- {
- // dito
- file->seek(0);
- if (SurfaceLoader[i]->isALoadableFileFormat(file))
- {
- if (loader)
- {
- *loader = SurfaceLoader[i];
- return 0;
- }
- file->seek(0);
- image = SurfaceLoader[i]->loadImage(file);
- if (image)
- return image;
- }
- }
- return 0; // failed to load
- }
- //! Writes the provided image to disk file
- bool CNullDriver::writeImageToFile(IImage* image, const io::path& filename,u32 param)
- {
- io::IWriteFile* file = FileSystem->createAndWriteFile(filename);
- if(!file)
- return false;
- bool result = writeImageToFile(image, file, param);
- file->drop();
- return result;
- }
- //! Writes the provided image to a file.
- bool CNullDriver::writeImageToFile(IImage* image, io::IWriteFile * file, u32 param)
- {
- if(!file)
- return false;
- for (s32 i=SurfaceWriter.size()-1; i>=0; --i)
- {
- if (SurfaceWriter[i]->isAWriteableFileExtension(file->getFileName()))
- {
- bool written = SurfaceWriter[i]->writeImage(file, image, param);
- if (written)
- return true;
- }
- }
- return false; // failed to write
- }
- //! Creates a software image from a byte array.
- IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format,
- const core::dimension2d<u32>& size,
- void *data, bool ownForeignMemory,
- bool deleteMemory)
- {
- if(IImage::isRenderTargetOnlyFormat(format))
- {
- os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING);
- return 0;
- }
- return new CImage(format, size, data, ownForeignMemory, deleteMemory);
- }
- //! Creates an empty software image.
- IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size)
- {
- if(IImage::isRenderTargetOnlyFormat(format))
- {
- os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING);
- return 0;
- }
- return new CImage(format, size);
- }
- //! Creates a software image from another image.
- IImage* CNullDriver::createImage(ECOLOR_FORMAT format, IImage *imageToCopy)
- {
- os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING);
- if(IImage::isRenderTargetOnlyFormat(format))
- {
- os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING);
- return 0;
- }
- CImage* tmp = new CImage(format, imageToCopy->getDimension());
- imageToCopy->copyTo(tmp);
- return tmp;
- }
- //! Creates a software image from part of another image.
- IImage* CNullDriver::createImage(IImage* imageToCopy, const core::position2d<s32>& pos, const core::dimension2d<u32>& size)
- {
- os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING);
- CImage* tmp = new CImage(imageToCopy->getColorFormat(), imageToCopy->getDimension());
- imageToCopy->copyTo(tmp, core::position2di(0,0), core::recti(pos,size));
- return tmp;
- }
- //! Creates a software image from part of a texture.
- IImage* CNullDriver::createImage(ITexture* texture, const core::position2d<s32>& pos, const core::dimension2d<u32>& size)
- {
- if ((pos==core::position2di(0,0)) && (size == texture->getSize()))
- {
- IImage* image = new CImage(texture->getColorFormat(), size, texture->lock(ETLM_READ_ONLY), false);
- texture->unlock();
- return image;
- }
- else
- {
- // make sure to avoid buffer overruns
- // make the vector a separate variable for g++ 3.x
- const core::vector2d<u32> leftUpper(core::clamp(static_cast<u32>(pos.X), 0u, texture->getSize().Width),
- core::clamp(static_cast<u32>(pos.Y), 0u, texture->getSize().Height));
- const core::rect<u32> clamped(leftUpper,
- core::dimension2du(core::clamp(static_cast<u32>(size.Width), 0u, texture->getSize().Width),
- core::clamp(static_cast<u32>(size.Height), 0u, texture->getSize().Height)));
- if (!clamped.isValid())
- return 0;
- u8* src = static_cast<u8*>(texture->lock(ETLM_READ_ONLY));
- if (!src)
- return 0;
- IImage* image = new CImage(texture->getColorFormat(), clamped.getSize());
- u8* dst = static_cast<u8*>(image->lock());
- src += clamped.UpperLeftCorner.Y * texture->getPitch() + image->getBytesPerPixel() * clamped.UpperLeftCorner.X;
- for (u32 i=0; i<clamped.getHeight(); ++i)
- {
- video::CColorConverter::convert_viaFormat(src, texture->getColorFormat(), clamped.getWidth(), dst, image->getColorFormat());
- src += texture->getPitch();
- dst += image->getPitch();
- }
- image->unlock();
- texture->unlock();
- return image;
- }
- }
- //! Sets the fog mode.
- void CNullDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, f32 end,
- f32 density, bool pixelFog, bool rangeFog)
- {
- FogColor = color;
- FogType = fogType;
- FogStart = start;
- FogEnd = end;
- FogDensity = density;
- PixelFog = pixelFog;
- RangeFog = rangeFog;
- }
- //! Gets the fog mode.
- void CNullDriver::getFog(SColor& color, E_FOG_TYPE& fogType, f32& start, f32& end,
- f32& density, bool& pixelFog, bool& rangeFog)
- {
- color = FogColor;
- fogType = FogType;
- start = FogStart;
- end = FogEnd;
- density = FogDensity;
- pixelFog = PixelFog;
- rangeFog = RangeFog;
- }
- //! Draws a mesh buffer
- void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb)
- {
- if (!mb)
- return;
- //IVertexBuffer and IIndexBuffer later
- SHWBufferLink *HWBuffer=getBufferLink(mb);
- if (HWBuffer)
- drawHardwareBuffer(HWBuffer);
- else
- drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), indiceToPrimitiveCount(mb->getPrimitiveType(), mb->getIndexCount()), mb->getVertexType(), mb->getPrimitiveType(), mb->getIndexType());
- }
- //! Draws the normals of a mesh buffer
- void CNullDriver::drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length, SColor color)
- {
- const u32 count = mb->getVertexCount();
- const bool normalize = mb->getMaterial().NormalizeNormals;
- for (u32 i=0; i < count; ++i)
- {
- core::vector3df normalizedNormal = mb->getNormal(i);
- if (normalize)
- normalizedNormal.normalize();
- const core::vector3df& pos = mb->getPosition(i);
- draw3DLine(pos, pos + (normalizedNormal * length), color);
- }
- }
- CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb)
- {
- if (!mb || !isHardwareBufferRecommend(mb))
- return 0;
- //search for hardware links
- core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb);
- if (node)
- return node->getValue();
- return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it
- }
- //! Update all hardware buffers, remove unused ones
- void CNullDriver::updateAllHardwareBuffers()
- {
- core::map<const scene::IMeshBuffer*,SHWBufferLink*>::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator();
- for (;!Iterator.atEnd();Iterator++)
- {
- SHWBufferLink *Link=Iterator.getNode()->getValue();
- Link->LastUsed++;
- if (Link->LastUsed>20000)
- {
- deleteHardwareBuffer(Link);
- // todo: needs better fix
- Iterator = HWBufferMap.getParentFirstIterator();
- }
- }
- }
- void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer)
- {
- if (!HWBuffer)
- return;
- HWBufferMap.remove(HWBuffer->MeshBuffer);
- delete HWBuffer;
- }
- //! Remove hardware buffer
- void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb)
- {
- core::map<const scene::IMeshBuffer*,SHWBufferLink*>::Node* node = HWBufferMap.find(mb);
- if (node)
- deleteHardwareBuffer(node->getValue());
- }
- //! Remove all hardware buffers
- void CNullDriver::removeAllHardwareBuffers()
- {
- while (HWBufferMap.size())
- deleteHardwareBuffer(HWBufferMap.getRoot()->getValue());
- }
- bool CNullDriver::isHardwareBufferRecommend(const scene::IMeshBuffer* mb)
- {
- if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER))
- return false;
- if (mb->getVertexCount()<MinVertexCountForVBO)
- return false;
- return true;
- }
- //! Create occlusion query.
- /** Use node for identification and mesh for occlusion test. */
- void CNullDriver::addOcclusionQuery(scene::ISceneNode* node, const scene::IMesh* mesh)
- {
- if (!node)
- return;
- if (!mesh)
- {
- if ((node->getType() != scene::ESNT_MESH) && (node->getType() != scene::ESNT_ANIMATED_MESH))
- return;
- else if (node->getType() == scene::ESNT_MESH)
- mesh = static_cast<scene::IMeshSceneNode*>(node)->getMesh();
- else
- mesh = static_cast<scene::IAnimatedMeshSceneNode*>(node)->getMesh()->getMesh(0);
- if (!mesh)
- return;
- }
- //search for query
- s32 index = OcclusionQueries.linear_search(SOccQuery(node));
- if (index != -1)
- {
- if (OcclusionQueries[index].Mesh != mesh)
- {
- OcclusionQueries[index].Mesh->drop();
- OcclusionQueries[index].Mesh = mesh;
- mesh->grab();
- }
- }
- else
- {
- OcclusionQueries.push_back(SOccQuery(node, mesh));
- node->setAutomaticCulling(node->getAutomaticCulling() | scene::EAC_OCC_QUERY);
- }
- }
- //! Remove occlusion query.
- void CNullDriver::removeOcclusionQuery(scene::ISceneNode* node)
- {
- //search for query
- s32 index = OcclusionQueries.linear_search(SOccQuery(node));
- if (index != -1)
- {
- node->setAutomaticCulling(node->getAutomaticCulling() & ~scene::EAC_OCC_QUERY);
- OcclusionQueries.erase(index);
- }
- }
- //! Remove all occlusion queries.
- void CNullDriver::removeAllOcclusionQueries()
- {
- for (s32 i=OcclusionQueries.size()-1; i>=0; --i)
- {
- removeOcclusionQuery(OcclusionQueries[i].Node);
- }
- }
- //! Run occlusion query. Draws mesh stored in query.
- /** If the mesh shall be rendered visible, use
- flag to enable the proper material setting. */
- void CNullDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible)
- {
- if(!node)
- return;
- s32 index = OcclusionQueries.linear_search(SOccQuery(node));
- if (index==-1)
- return;
- OcclusionQueries[index].Run=0;
- if (!visible)
- {
- SMaterial mat;
- mat.Lighting=false;
- mat.AntiAliasing=0;
- mat.ColorMask=ECP_NONE;
- mat.GouraudShading=false;
- mat.ZWriteEnable=false;
- setMaterial(mat);
- }
- setTransform(video::ETS_WORLD, node->getAbsoluteTransformation());
- const scene::IMesh* mesh = OcclusionQueries[index].Mesh;
- for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
- {
- if (visible)
- setMaterial(mesh->getMeshBuffer(i)->getMaterial());
- drawMeshBuffer(mesh->getMeshBuffer(i));
- }
- }
- //! Run all occlusion queries. Draws all meshes stored in queries.
- /** If the meshes shall not be rendered visible, use
- overrideMaterial to disable the color and depth buffer. */
- void CNullDriver::runAllOcclusionQueries(bool visible)
- {
- for (u32 i=0; i<OcclusionQueries.size(); ++i)
- runOcclusionQuery(OcclusionQueries[i].Node, visible);
- }
- //! Update occlusion query. Retrieves results from GPU.
- /** If the query shall not block, set the flag to false.
- Update might not occur in this case, though */
- void CNullDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block)
- {
- }
- //! Update all occlusion queries. Retrieves results from GPU.
- /** If the query shall not block, set the flag to false.
- Update might not occur in this case, though */
- void CNullDriver::updateAllOcclusionQueries(bool block)
- {
- for (u32 i=0; i<OcclusionQueries.size(); ++i)
- {
- if (OcclusionQueries[i].Run==u32(~0))
- continue;
- updateOcclusionQuery(OcclusionQueries[i].Node, block);
- ++OcclusionQueries[i].Run;
- if (OcclusionQueries[i].Run>1000)
- removeOcclusionQuery(OcclusionQueries[i].Node);
- }
- }
- //! Return query result.
- /** Return value is the number of visible pixels/fragments.
- The value is a safe approximation, i.e. can be larger then the
- actual value of pixels. */
- u32 CNullDriver::getOcclusionQueryResult(scene::ISceneNode* node) const
- {
- return ~0;
- }
- //! Only used by the internal engine. Used to notify the driver that
- //! the window was resized.
- void CNullDriver::OnResize(const core::dimension2d<u32>& size)
- {
- if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
- ViewPort.getHeight() == (s32)ScreenSize.Height)
- ViewPort = core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(size));
- ScreenSize = size;
- }
- // adds a material renderer and drops it afterwards. To be used for internal creation
- s32 CNullDriver::addAndDropMaterialRenderer(IMaterialRenderer* m)
- {
- s32 i = addMaterialRenderer(m);
- if (m)
- m->drop();
- return i;
- }
- //! Adds a new material renderer to the video device.
- s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* name)
- {
- if (!renderer)
- return -1;
- SMaterialRenderer r;
- r.Renderer = renderer;
- r.Name = name;
- if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 ))
- {
- // set name of built in renderer so that we don't have to implement name
- // setting in all available renderers.
- r.Name = sBuiltInMaterialTypeNames[MaterialRenderers.size()];
- }
- MaterialRenderers.push_back(r);
- renderer->grab();
- return MaterialRenderers.size()-1;
- }
- //! Sets the name of a material renderer.
- void CNullDriver::setMaterialRendererName(s32 idx, const char* name)
- {
- if (idx < s32(sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 ||
- idx >= (s32)MaterialRenderers.size())
- return;
- MaterialRenderers[idx].Name = name;
- }
- //! Creates material attributes list from a material, usable for serialization and more.
- io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material,
- io::SAttributeReadWriteOptions* options)
- {
- io::CAttributes* attr = new io::CAttributes(this);
- attr->addEnum("Type", material.MaterialType, sBuiltInMaterialTypeNames);
- attr->addColor("Ambient", material.AmbientColor);
- attr->addColor("Diffuse", material.DiffuseColor);
- attr->addColor("Emissive", material.EmissiveColor);
- attr->addColor("Specular", material.SpecularColor);
- attr->addFloat("Shininess", material.Shininess);
- attr->addFloat("Param1", material.MaterialTypeParam);
- attr->addFloat("Param2", material.MaterialTypeParam2);
- core::stringc prefix="Texture";
- u32 i;
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- {
- if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename && material.getTexture(i))
- {
- io::path path = FileSystem->getRelativeFilename(
- FileSystem->getAbsolutePath(material.getTexture(i)->getName()), options->Filename);
- attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i), path);
- }
- else
- attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i));
- }
- attr->addBool("Wireframe", material.Wireframe);
- attr->addBool("GouraudShading", material.GouraudShading);
- attr->addBool("Lighting", material.Lighting);
- attr->addBool("ZWriteEnable", material.ZWriteEnable);
- attr->addInt("ZBuffer", material.ZBuffer);
- attr->addBool("BackfaceCulling", material.BackfaceCulling);
- attr->addBool("FrontfaceCulling", material.FrontfaceCulling);
- attr->addBool("FogEnable", material.FogEnable);
- attr->addBool("NormalizeNormals", material.NormalizeNormals);
- attr->addBool("UseMipMaps", material.UseMipMaps);
- attr->addInt("AntiAliasing", material.AntiAliasing);
- attr->addInt("ColorMask", material.ColorMask);
- attr->addInt("ColorMaterial", material.ColorMaterial);
- attr->addInt("PolygonOffsetFactor", material.PolygonOffsetFactor);
- attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames);
- prefix = "BilinearFilter";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].BilinearFilter);
- prefix = "TrilinearFilter";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TrilinearFilter);
- prefix = "AnisotropicFilter";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter);
- prefix="TextureWrapU";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapU, aTextureClampNames);
- prefix="TextureWrapV";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames);
- prefix="LODBias";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias);
- return attr;
- }
- //! Fills an SMaterial structure from attributes.
- void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attr)
- {
- outMaterial.MaterialType = video::EMT_SOLID;
- core::stringc name = attr->getAttributeAsString("Type");
- u32 i;
- for ( i=0; i < MaterialRenderers.size(); ++i)
- if ( name == MaterialRenderers[i].Name )
- {
- outMaterial.MaterialType = (video::E_MATERIAL_TYPE)i;
- break;
- }
- outMaterial.AmbientColor = attr->getAttributeAsColor("Ambient");
- outMaterial.DiffuseColor = attr->getAttributeAsColor("Diffuse");
- outMaterial.EmissiveColor = attr->getAttributeAsColor("Emissive");
- outMaterial.SpecularColor = attr->getAttributeAsColor("Specular");
- outMaterial.Shininess = attr->getAttributeAsFloat("Shininess");
- outMaterial.MaterialTypeParam = attr->getAttributeAsFloat("Param1");
- outMaterial.MaterialTypeParam2 = attr->getAttributeAsFloat("Param2");
- core::stringc prefix="Texture";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- outMaterial.setTexture(i, attr->getAttributeAsTexture((prefix+core::stringc(i+1)).c_str()));
- outMaterial.Wireframe = attr->getAttributeAsBool("Wireframe");
- outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading");
- outMaterial.Lighting = attr->getAttributeAsBool("Lighting");
- outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable");
- outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer");
- outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling");
- outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling");
- outMaterial.FogEnable = attr->getAttributeAsBool("FogEnable");
- outMaterial.NormalizeNormals = attr->getAttributeAsBool("NormalizeNormals");
- if (attr->existsAttribute("UseMipMaps")) // legacy
- outMaterial.UseMipMaps = attr->getAttributeAsBool("UseMipMaps");
- else
- outMaterial.UseMipMaps = true;
- // default 0 is ok
- outMaterial.AntiAliasing = attr->getAttributeAsInt("AntiAliasing");
- if (attr->existsAttribute("ColorMask"))
- outMaterial.ColorMask = attr->getAttributeAsInt("ColorMask");
- if (attr->existsAttribute("ColorMaterial"))
- outMaterial.ColorMaterial = attr->getAttributeAsInt("ColorMaterial");
- if (attr->existsAttribute("PolygonOffsetFactor"))
- outMaterial.PolygonOffsetFactor = attr->getAttributeAsInt("PolygonOffsetFactor");
- if (attr->existsAttribute("PolygonOffsetDirection"))
- outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames);
- prefix = "BilinearFilter";
- if (attr->existsAttribute(prefix.c_str())) // legacy
- outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str()));
- else
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- outMaterial.TextureLayer[i].BilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str());
- prefix = "TrilinearFilter";
- if (attr->existsAttribute(prefix.c_str())) // legacy
- outMaterial.setFlag(EMF_TRILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str()));
- else
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- outMaterial.TextureLayer[i].TrilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str());
- prefix = "AnisotropicFilter";
- if (attr->existsAttribute(prefix.c_str())) // legacy
- outMaterial.setFlag(EMF_ANISOTROPIC_FILTER, attr->getAttributeAsBool(prefix.c_str()));
- else
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- outMaterial.TextureLayer[i].AnisotropicFilter = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str());
- prefix = "TextureWrap";
- if (attr->existsAttribute(prefix.c_str())) // legacy
- {
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- {
- outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames);
- outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU;
- }
- }
- else
- {
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- {
- outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames);
- outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames);
- }
- }
- // default 0 is ok
- prefix="LODBias";
- for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
- outMaterial.TextureLayer[i].LODBias = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str());
- }
- //! Returns driver and operating system specific data about the IVideoDriver.
- const SExposedVideoData& CNullDriver::getExposedVideoData()
- {
- return ExposedData;
- }
- //! Returns type of video driver
- E_DRIVER_TYPE CNullDriver::getDriverType() const
- {
- return EDT_NULL;
- }
- //! deletes all material renderers
- void CNullDriver::deleteMaterialRenders()
- {
- // delete material renderers
- for (u32 i=0; i<MaterialRenderers.size(); ++i)
- if (MaterialRenderers[i].Renderer)
- MaterialRenderers[i].Renderer->drop();
- MaterialRenderers.clear();
- }
- //! Returns pointer to material renderer or null
- IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx)
- {
- if ( idx < MaterialRenderers.size() )
- return MaterialRenderers[idx].Renderer;
- else
- return 0;
- }
- //! Returns amount of currently available material renderers.
- u32 CNullDriver::getMaterialRendererCount() const
- {
- return MaterialRenderers.size();
- }
- //! Returns name of the material renderer
- const char* CNullDriver::getMaterialRendererName(u32 idx) const
- {
- if ( idx < MaterialRenderers.size() )
- return MaterialRenderers[idx].Name.c_str();
- return 0;
- }
- //! Returns pointer to the IGPUProgrammingServices interface.
- IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices()
- {
- return this;
- }
- //! Adds a new material renderer to the VideoDriver, based on a high level shading language.
- s32 CNullDriver::addHighLevelShaderMaterial(
- const c8* vertexShaderProgram,
- const c8* vertexShaderEntryPointName,
- E_VERTEX_SHADER_TYPE vsCompileTarget,
- const c8* pixelShaderProgram,
- const c8* pixelShaderEntryPointName,
- E_PIXEL_SHADER_TYPE psCompileTarget,
- const c8* geometryShaderProgram,
- const c8* geometryShaderEntryPointName,
- E_GEOMETRY_SHADER_TYPE gsCompileTarget,
- scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
- u32 verticesOut,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
- {
- os::Printer::log("High level shader materials not available (yet) in this driver, sorry");
- return -1;
- }
- //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
- //! but tries to load the programs from files.
- s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
- const io::path& vertexShaderProgramFileName,
- const c8* vertexShaderEntryPointName,
- E_VERTEX_SHADER_TYPE vsCompileTarget,
- const io::path& pixelShaderProgramFileName,
- const c8* pixelShaderEntryPointName,
- E_PIXEL_SHADER_TYPE psCompileTarget,
- const io::path& geometryShaderProgramFileName,
- const c8* geometryShaderEntryPointName,
- E_GEOMETRY_SHADER_TYPE gsCompileTarget,
- scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
- u32 verticesOut,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
- {
- io::IReadFile* vsfile = 0;
- io::IReadFile* psfile = 0;
- io::IReadFile* gsfile = 0;
- if (vertexShaderProgramFileName.size() )
- {
- vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName);
- if (!vsfile)
- {
- os::Printer::log("Could not open vertex shader program file",
- vertexShaderProgramFileName, ELL_WARNING);
- }
- }
- if (pixelShaderProgramFileName.size() )
- {
- psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName);
- if (!psfile)
- {
- os::Printer::log("Could not open pixel shader program file",
- pixelShaderProgramFileName, ELL_WARNING);
- }
- }
- if (geometryShaderProgramFileName.size() )
- {
- gsfile = FileSystem->createAndOpenFile(geometryShaderProgramFileName);
- if (!gsfile)
- {
- os::Printer::log("Could not open geometry shader program file",
- geometryShaderProgramFileName, ELL_WARNING);
- }
- }
- s32 result = addHighLevelShaderMaterialFromFiles(
- vsfile, vertexShaderEntryPointName, vsCompileTarget,
- psfile, pixelShaderEntryPointName, psCompileTarget,
- gsfile, geometryShaderEntryPointName, gsCompileTarget,
- inType, outType, verticesOut,
- callback, baseMaterial, userData, shadingLang);
- if (psfile)
- psfile->drop();
- if (vsfile)
- vsfile->drop();
- if (gsfile)
- gsfile->drop();
- return result;
- }
- //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
- //! but tries to load the programs from files.
- s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
- io::IReadFile* vertexShaderProgram,
- const c8* vertexShaderEntryPointName,
- E_VERTEX_SHADER_TYPE vsCompileTarget,
- io::IReadFile* pixelShaderProgram,
- const c8* pixelShaderEntryPointName,
- E_PIXEL_SHADER_TYPE psCompileTarget,
- io::IReadFile* geometryShaderProgram,
- const c8* geometryShaderEntryPointName,
- E_GEOMETRY_SHADER_TYPE gsCompileTarget,
- scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
- u32 verticesOut,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
- {
- c8* vs = 0;
- c8* ps = 0;
- c8* gs = 0;
- if (vertexShaderProgram)
- {
- const long size = vertexShaderProgram->getSize();
- if (size)
- {
- vs = new c8[size+1];
- vertexShaderProgram->read(vs, size);
- vs[size] = 0;
- }
- }
- if (pixelShaderProgram)
- {
- const long size = pixelShaderProgram->getSize();
- if (size)
- {
- // if both handles are the same we must reset the file
- if (pixelShaderProgram==vertexShaderProgram)
- pixelShaderProgram->seek(0);
- ps = new c8[size+1];
- pixelShaderProgram->read(ps, size);
- ps[size] = 0;
- }
- }
- if (geometryShaderProgram)
- {
- const long size = geometryShaderProgram->getSize();
- if (size)
- {
- // if both handles are the same we must reset the file
- if ((geometryShaderProgram==vertexShaderProgram) ||
- (geometryShaderProgram==pixelShaderProgram))
- geometryShaderProgram->seek(0);
- gs = new c8[size+1];
- geometryShaderProgram->read(gs, size);
- gs[size] = 0;
- }
- }
- s32 result = this->addHighLevelShaderMaterial(
- vs, vertexShaderEntryPointName, vsCompileTarget,
- ps, pixelShaderEntryPointName, psCompileTarget,
- gs, geometryShaderEntryPointName, gsCompileTarget,
- inType, outType, verticesOut,
- callback, baseMaterial, userData, shadingLang);
- delete [] vs;
- delete [] ps;
- delete [] gs;
- return result;
- }
- //! Adds a new material renderer to the VideoDriver, using pixel and/or
- //! vertex shaders to render geometry.
- s32 CNullDriver::addShaderMaterial(const c8* vertexShaderProgram,
- const c8* pixelShaderProgram,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData)
- {
- os::Printer::log("Shader materials not implemented yet in this driver, sorry.");
- return -1;
- }
- //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the
- //! programs from files.
- s32 CNullDriver::addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram,
- io::IReadFile* pixelShaderProgram,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData)
- {
- c8* vs = 0;
- c8* ps = 0;
- if (vertexShaderProgram)
- {
- const long size = vertexShaderProgram->getSize();
- if (size)
- {
- vs = new c8[size+1];
- vertexShaderProgram->read(vs, size);
- vs[size] = 0;
- }
- }
- if (pixelShaderProgram)
- {
- const long size = pixelShaderProgram->getSize();
- if (size)
- {
- ps = new c8[size+1];
- pixelShaderProgram->read(ps, size);
- ps[size] = 0;
- }
- }
- s32 result = addShaderMaterial(vs, ps, callback, baseMaterial, userData);
- delete [] vs;
- delete [] ps;
- return result;
- }
- //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the
- //! programs from files.
- s32 CNullDriver::addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName,
- const io::path& pixelShaderProgramFileName,
- IShaderConstantSetCallBack* callback,
- E_MATERIAL_TYPE baseMaterial,
- s32 userData)
- {
- io::IReadFile* vsfile = 0;
- io::IReadFile* psfile = 0;
- if (vertexShaderProgramFileName.size())
- {
- vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName);
- if (!vsfile)
- {
- os::Printer::log("Could not open vertex shader program file",
- vertexShaderProgramFileName, ELL_WARNING);
- return -1;
- }
- }
- if (pixelShaderProgramFileName.size())
- {
- psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName);
- if (!psfile)
- {
- os::Printer::log("Could not open pixel shader program file",
- pixelShaderProgramFileName, ELL_WARNING);
- if (vsfile)
- vsfile->drop();
- return -1;
- }
- }
- s32 result = addShaderMaterialFromFiles(vsfile, psfile, callback,
- baseMaterial, userData);
- if (psfile)
- psfile->drop();
- if (vsfile)
- vsfile->drop();
- return result;
- }
- //! Creates a render target texture.
- ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
- const io::path&name, const ECOLOR_FORMAT format,
- const bool useStencil)
- {
- return 0;
- }
- //! Clears the ZBuffer.
- void CNullDriver::clearZBuffer()
- {
- }
- //! Returns a pointer to the mesh manipulator.
- scene::IMeshManipulator* CNullDriver::getMeshManipulator()
- {
- return MeshManipulator;
- }
- //! Returns an image created from the last rendered frame.
- IImage* CNullDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
- {
- return 0;
- }
- // prints renderer version
- void CNullDriver::printVersion()
- {
- core::stringw namePrint = L"Using renderer: ";
- namePrint += getName();
- os::Printer::log(namePrint.c_str(), ELL_INFORMATION);
- }
- //! creates a video driver
- IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
- {
- CNullDriver* nullDriver = new CNullDriver(io, screenSize);
- // create empty material renderers
- for(u32 i=0; sBuiltInMaterialTypeNames[i]; ++i)
- {
- IMaterialRenderer* imr = new IMaterialRenderer();
- nullDriver->addMaterialRenderer(imr);
- imr->drop();
- }
- return nullDriver;
- }
- //! Set/unset a clipping plane.
- //! There are at least 6 clipping planes available for the user to set at will.
- //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes.
- //! \param plane: The plane itself.
- //! \param enable: If true, enable the clipping plane else disable it.
- bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable)
- {
- return false;
- }
- //! Enable/disable a clipping plane.
- void CNullDriver::enableClipPlane(u32 index, bool enable)
- {
- // not necessary
- }
- ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d<u32>& size,
- const c8* name)
- {
- os::Printer::log("createRenderTargetTexture is deprecated, use addRenderTargetTexture instead");
- ITexture* tex = addRenderTargetTexture(size, name);
- tex->grab();
- return tex;
- }
- void CNullDriver::setMinHardwareBufferVertexCount(u32 count)
- {
- MinVertexCountForVBO = count;
- }
- SOverrideMaterial& CNullDriver::getOverrideMaterial()
- {
- return OverrideMaterial;
- }
- //! Get the 2d override material for altering its values
- SMaterial& CNullDriver::getMaterial2D()
- {
- return OverrideMaterial2D;
- }
- //! Enable the 2d override material
- void CNullDriver::enableMaterial2D(bool enable)
- {
- OverrideMaterial2DEnabled=enable;
- }
- core::dimension2du CNullDriver::getMaxTextureSize() const
- {
- return core::dimension2du(0x10000,0x10000); // maybe large enough
- }
- //! Color conversion convenience function
- /** Convert an image (as array of pixels) from source to destination
- array, thereby converting the color format. The pixel size is
- determined by the color formats.
- \param sP Pointer to source
- \param sF Color format of source
- \param sN Number of pixels to convert, both array must be large enough
- \param dP Pointer to destination
- \param dF Color format of destination
- */
- void CNullDriver::convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN,
- void* dP, ECOLOR_FORMAT dF) const
- {
- video::CColorConverter::convert_viaFormat(sP, sF, sN, dP, dF);
- }
- u32 CNullDriver::indiceToPrimitiveCount(scene::E_PRIMITIVE_TYPE ptype, u32 count) const
- {
- switch (ptype)
- {
- case scene::EPT_POINTS:
- case scene::EPT_POINT_SPRITES:
- case scene::EPT_LINE_LOOP:
- case scene::EPT_POLYGON:
- return count;
- case scene::EPT_LINE_STRIP:
- return count - 1;
- case scene::EPT_LINES:
- return count/2;
- case scene::EPT_TRIANGLE_STRIP:
- case scene::EPT_TRIANGLE_FAN:
- return count - 2;
- case scene::EPT_TRIANGLES:
- return count/3;
- case scene::EPT_QUAD_STRIP:
- return (count - 2) / 2;
- case scene::EPT_QUADS:
- return count/4;
- default:
- return count;
- }
- }
- } // end namespace
- } // end namespace
|