Merge branch 'new_texture_format'

This commit is contained in:
Benau 2017-01-10 09:09:38 +08:00
commit 8acd2d689a
74 changed files with 2794 additions and 3587 deletions

View File

@ -64,7 +64,6 @@ endif()
set(IRRLICHT_SOURCES set(IRRLICHT_SOURCES
source/Irrlicht/CAnimatedMeshSceneNode.cpp source/Irrlicht/CAnimatedMeshSceneNode.cpp
source/Irrlicht/CAttributes.cpp source/Irrlicht/CAttributes.cpp
source/Irrlicht/CB3DMeshFileLoader.cpp
source/Irrlicht/CBillboardSceneNode.cpp source/Irrlicht/CBillboardSceneNode.cpp
source/Irrlicht/CBoneSceneNode.cpp source/Irrlicht/CBoneSceneNode.cpp
source/Irrlicht/CCameraSceneNode.cpp source/Irrlicht/CCameraSceneNode.cpp
@ -192,11 +191,9 @@ source/Irrlicht/Irrlicht.cpp
source/Irrlicht/irrXML.cpp source/Irrlicht/irrXML.cpp
source/Irrlicht/os.cpp source/Irrlicht/os.cpp
source/Irrlicht/COpenGLNormalMapRenderer.cpp source/Irrlicht/COpenGLNormalMapRenderer.cpp
source/Irrlicht/BuiltInFont.h
source/Irrlicht/CAnimatedMeshSceneNode.h source/Irrlicht/CAnimatedMeshSceneNode.h
source/Irrlicht/CAttributeImpl.h source/Irrlicht/CAttributeImpl.h
source/Irrlicht/CAttributes.h source/Irrlicht/CAttributes.h
source/Irrlicht/CB3DMeshFileLoader.h
source/Irrlicht/CBillboardSceneNode.h source/Irrlicht/CBillboardSceneNode.h
source/Irrlicht/CBlit.h source/Irrlicht/CBlit.h
source/Irrlicht/CBoneSceneNode.h source/Irrlicht/CBoneSceneNode.h

View File

@ -95,8 +95,6 @@ public:
\param s String of symbols which are not send down to the videodriver \param s String of symbols which are not send down to the videodriver
*/ */
virtual void setInvisibleCharacters( const wchar_t *s ) = 0; virtual void setInvisibleCharacters( const wchar_t *s ) = 0;
virtual u32 addLazyLoadCharacters(const wchar_t *s) { return 0; }
}; };
} // end namespace gui } // end namespace gui

View File

@ -104,6 +104,8 @@ public:
{ {
} }
virtual ~ITexture() {}
//! Lock function. //! Lock function.
/** Locks the Texture and returns a pointer to access the /** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels pixels. After lock() has been called and all operations on the pixels
@ -190,6 +192,12 @@ public:
//! Get name of texture (in most cases this is the filename) //! Get name of texture (in most cases this is the filename)
const io::SNamedPath& getName() const { return NamedPath; } const io::SNamedPath& getName() const { return NamedPath; }
//! return open gl texture name
virtual u32 getOpenGLTextureName() const = 0;
virtual u64 getHandle() = 0;
virtual void unloadHandle() {}
protected: protected:
//! Helper function, helps to get the desired texture creation format from the flags. //! Helper function, helps to get the desired texture creation format from the flags.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,140 +0,0 @@
// Copyright (C) 2006-2012 Luke Hoschke
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// B3D Mesh loader
// File format designed by Mark Sibly for the Blitz3D engine and has been
// declared public domain
#include "IrrCompileConfig.h"
#ifndef __C_B3D_MESH_LOADER_H_INCLUDED__
#define __C_B3D_MESH_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "ISceneManager.h"
#include "CSkinnedMesh.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
//! Meshloader for B3D format
class CB3DMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CB3DMeshFileLoader(scene::ISceneManager* smgr);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
struct SB3dChunkHeader
{
c8 name[4];
s32 size;
};
struct SB3dChunk
{
SB3dChunk(const SB3dChunkHeader& header, long sp)
: length(header.size+8), startposition(sp)
{
name[0]=header.name[0];
name[1]=header.name[1];
name[2]=header.name[2];
name[3]=header.name[3];
}
c8 name[4];
s32 length;
long startposition;
};
struct SB3dTexture
{
core::stringc TextureName;
s32 Flags;
s32 Blend;
f32 Xpos;
f32 Ypos;
f32 Xscale;
f32 Yscale;
f32 Angle;
};
struct SB3dMaterial
{
SB3dMaterial() : red(1.0f), green(1.0f),
blue(1.0f), alpha(1.0f), shininess(0.0f), blend(1),
fx(0)
{
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
Textures[i]=0;
}
video::SMaterial Material;
f32 red, green, blue, alpha;
f32 shininess;
s32 blend,fx;
SB3dTexture *Textures[video::MATERIAL_MAX_TEXTURES];
};
bool load();
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
bool readChunkVRTS(CSkinnedMesh::SJoint* InJoint);
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(CSkinnedMesh::SJoint* InJoint);
bool readChunkKEYS(CSkinnedMesh::SJoint* InJoint);
bool readChunkANIM();
bool readChunkTEXS();
bool readChunkBRUS();
void loadTextures(SB3dMaterial& material) const;
void readString(core::stringc& newstring);
void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<s32> AnimatedVertices_VertexID;
core::array<s32> AnimatedVertices_BufferID;
core::array<video::S3DVertex2TCoords> BaseVertices;
ISceneManager* SceneManager;
CSkinnedMesh* AnimatedMesh;
io::IReadFile* B3DFile;
//B3Ds have Vertex ID's local within the mesh I don't want this
// Variable needs to be class member due to recursion in calls
u32 VerticesStart;
bool NormalsInFile;
bool HasVertexColors;
bool ShowWarning;
};
} // end namespace scene
} // end namespace irr
#endif // __C_B3D_MESH_LOADER_H_INCLUDED__

View File

@ -40,7 +40,6 @@
#include "IWriteFile.h" #include "IWriteFile.h"
#include "IXMLWriter.h" #include "IXMLWriter.h"
#include "BuiltInFont.h"
#include "os.h" #include "os.h"
namespace irr namespace irr
@ -78,8 +77,6 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
registerGUIElementFactory(factory); registerGUIElementFactory(factory);
factory->drop(); factory->drop();
loadBuiltInFont();
IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC ); IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC );
setSkin(skin); setSkin(skin);
skin->drop(); skin->drop();
@ -165,29 +162,6 @@ CGUIEnvironment::~CGUIEnvironment()
} }
} }
void CGUIEnvironment::loadBuiltInFont()
{
io::IReadFile* file = io::createMemoryReadFile(BuiltInFontData, BuiltInFontDataSize, DefaultFontName, false);
CGUIFont* font = new CGUIFont(this, DefaultFontName );
if (!font->load(file))
{
os::Printer::log("Error: Could not load built-in Font. Did you compile without the BMP loader?", ELL_ERROR);
font->drop();
file->drop();
return;
}
SFont f;
f.NamedPath.setPath(DefaultFontName);
f.Font = font;
Fonts.push_back(f);
file->drop();
}
//! draws all gui elements //! draws all gui elements
void CGUIEnvironment::drawAll() void CGUIEnvironment::drawAll()
{ {

View File

@ -262,8 +262,6 @@ private:
void updateHoveredElement(core::position2d<s32> mousePos); void updateHoveredElement(core::position2d<s32> mousePos);
void loadBuiltInFont();
struct SFont struct SFont
{ {
io::SNamedPath NamedPath; io::SNamedPath NamedPath;

View File

@ -568,30 +568,30 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig, boo
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 0; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
if(!force_legacy_context)
{
// create core 4.3 context
os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx);
if (!XErrorSignaled)
return Context;
XErrorSignaled = false;
// create core 3.3 context
os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx);
if (!XErrorSignaled)
return Context;
XErrorSignaled = false; if(!force_legacy_context)
// create core 3.1 context (for older mesa) {
os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION); // create core 4.3 context
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx); os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION);
if (!XErrorSignaled) Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx);
return Context; if (!XErrorSignaled)
return Context;
} // if(force_legacy_context) XErrorSignaled = false;
// create core 3.3 context
os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx);
if (!XErrorSignaled)
return Context;
XErrorSignaled = false;
// create core 3.1 context (for older mesa)
os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx);
if (!XErrorSignaled)
return Context;
} // if(force_legacy_context)
XErrorSignaled = false; XErrorSignaled = false;
irr::video::useCoreContext = false; irr::video::useCoreContext = false;
@ -626,7 +626,7 @@ bool CIrrDeviceLinux::createWindow()
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
GLXFBConfig glxFBConfig; GLXFBConfig glxFBConfig = NULL;
int major, minor; int major, minor;
bool isAvailableGLX=false; bool isAvailableGLX=false;
if (CreationParams.DriverType==video::EDT_OPENGL) if (CreationParams.DriverType==video::EDT_OPENGL)
@ -1044,7 +1044,9 @@ bool CIrrDeviceLinux::createWindow()
glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); glxWin=glXCreateWindow(display,glxFBConfig,window,NULL);
if (glxWin) if (glxWin)
{ {
getLogger()->setLogLevel(ELL_NONE);
Context = getMeAGLContext(display, glxFBConfig, CreationParams.ForceLegacyDevice); Context = getMeAGLContext(display, glxFBConfig, CreationParams.ForceLegacyDevice);
getLogger()->setLogLevel(CreationParams.LoggingLevel);
if (Context) if (Context)
{ {
if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) if (!glXMakeContextCurrent(display, glxWin, glxWin, Context))

View File

@ -744,6 +744,8 @@ namespace video
virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; } virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; }
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; }; virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; };
virtual u32 getPitch() const { return 0; } virtual u32 getPitch() const { return 0; }
virtual u32 getOpenGLTextureName() const { return 0; }
virtual u64 getHandle() { return 0; }
virtual void regenerateMipMapLevels(void* mipmapData=0) {}; virtual void regenerateMipMapLevels(void* mipmapData=0) {};
core::dimension2d<u32> size; core::dimension2d<u32> size;
}; };

View File

@ -3120,7 +3120,7 @@ namespace video
setActiveTexture(GL_TEXTURE0 + stage); setActiveTexture(GL_TEXTURE0 + stage);
if(Driver->CurrentTexture[stage]) if(Driver->CurrentTexture[stage])
glBindTexture(GL_TEXTURE_2D, static_cast<const COGLES2Texture*>(Driver->CurrentTexture[stage])->getOpenGLTextureName()); glBindTexture(GL_TEXTURE_2D, Driver->CurrentTexture[stage]->getOpenGLTextureName());
Texture[stage] = Driver->CurrentTexture[stage]; Texture[stage] = Driver->CurrentTexture[stage];
} }

View File

@ -81,7 +81,9 @@ public:
virtual u32 getPitch() const; virtual u32 getPitch() const;
//! return open gl texture name //! return open gl texture name
GLuint getOpenGLTextureName() const; virtual u32 getOpenGLTextureName() const;
virtual u64 getHandle() { return 0; }
//! return whether this texture has mipmaps //! return whether this texture has mipmaps
virtual bool hasMipMaps() const; virtual bool hasMipMaps() const;

View File

@ -2565,8 +2565,7 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
if (!useCoreContext) if (!useCoreContext)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glBindTexture(GL_TEXTURE_2D, texture->getOpenGLTextureName());
static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
} }
return true; return true;
} }

View File

@ -16,7 +16,7 @@ namespace irr
{ {
namespace video namespace video
{ {
extern bool useCoreContext;
//! Constructor //! Constructor
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver,
@ -91,6 +91,9 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr,
{ {
outMaterialTypeNr = -1; outMaterialTypeNr = -1;
if (useCoreContext)
return;
bool success; bool success;
// create vertex shader // create vertex shader

View File

@ -78,7 +78,9 @@ public:
virtual u32 getPitch() const; virtual u32 getPitch() const;
//! return open gl texture name //! return open gl texture name
GLuint getOpenGLTextureName() const; virtual u32 getOpenGLTextureName() const;
virtual u64 getHandle() { return 0; }
//! return whether this texture has mipmaps //! return whether this texture has mipmaps
virtual bool hasMipMaps() const; virtual bool hasMipMaps() const;

View File

@ -24,10 +24,6 @@
#include "CSkinnedMesh.h" #include "CSkinnedMesh.h"
#endif #endif
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
#include "CB3DMeshFileLoader.h"
#endif
#include "CCubeSceneNode.h" #include "CCubeSceneNode.h"
#include "CSphereSceneNode.h" #include "CSphereSceneNode.h"
#include "CAnimatedMeshSceneNode.h" #include "CAnimatedMeshSceneNode.h"
@ -121,13 +117,6 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
// create geometry creator // create geometry creator
GeometryCreator = new CGeometryCreator(); GeometryCreator = new CGeometryCreator();
// add file format loaders. add the least commonly used ones first,
// as these are checked last
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
#endif
// factories // factories
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this); ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
registerSceneNodeFactory(factory); registerSceneNodeFactory(factory);
@ -1427,11 +1416,6 @@ void CSceneManager::drawAll(u32 flags)
void CSceneManager::setLightManager(ILightManager* lightManager) void CSceneManager::setLightManager(ILightManager* lightManager)
{ {
if (lightManager)
lightManager->grab();
if (LightManager)
LightManager->drop();
LightManager = lightManager; LightManager = lightManager;
} }

View File

@ -114,12 +114,10 @@ CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManag
{ {
Font = (gui::IGUIFontBitmap*)font; Font = (gui::IGUIFontBitmap*)font;
Font->grab(); Font->grab();
u32 texture_count = Font->addLazyLoadCharacters(text);
_IRR_DEBUG_BREAK_IF(texture_count==0);
// mesh with one buffer per texture // mesh with one buffer per texture
Mesh = new SMesh(); Mesh = new SMesh();
for (u32 i=0; i<texture_count; ++i) for (u32 i=0; i<Font->getSpriteBank()->getTextureCount(); ++i)
{ {
SMeshBuffer *mb = new SMeshBuffer(); SMeshBuffer *mb = new SMeshBuffer();
mb->Material = Material; mb->Material = Material;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file. # Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically. # This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -29,6 +29,8 @@ class FaceTTF;
class DigitFace : public FontWithFace class DigitFace : public FontWithFace
{ {
private: private:
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; } virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; } virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
@ -43,8 +45,6 @@ public:
virtual void init() OVERRIDE; virtual void init() OVERRIDE;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void reset() OVERRIDE; virtual void reset() OVERRIDE;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
}; // DigitFace }; // DigitFace

View File

@ -22,7 +22,10 @@
#include "font/font_manager.hpp" #include "font/font_manager.hpp"
#include "font/font_settings.hpp" #include "font/font_settings.hpp"
#include "graphics/2dutils.hpp" #include "graphics/2dutils.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/skin.hpp" #include "guiengine/skin.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
@ -50,8 +53,11 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
*/ */
FontWithFace::~FontWithFace() FontWithFace::~FontWithFace()
{ {
m_page->drop(); for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
m_page = NULL; {
STKTexManager::getInstance()->removeTexture(
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
}
m_spritebank->drop(); m_spritebank->drop();
m_spritebank = NULL; m_spritebank = NULL;
@ -66,9 +72,6 @@ FontWithFace::~FontWithFace()
void FontWithFace::init() void FontWithFace::init()
{ {
setDPI(); setDPI();
m_page = irr_driver->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
core::dimension2du(getGlyphPageSize(), getGlyphPageSize()));
// Get the max height for this face // Get the max height for this face
assert(m_face_ttf->getTotalFaces() > 0); assert(m_face_ttf->getTotalFaces() > 0);
FT_Face cur_face = m_face_ttf->getFace(0); FT_Face cur_face = m_face_ttf->getFace(0);
@ -129,32 +132,26 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
*/ */
void FontWithFace::createNewGlyphPage() void FontWithFace::createNewGlyphPage()
{ {
m_page->fill(video::SColor(0, 255, 255, 255)); #ifndef SERVER_ONLY
uint8_t* data = new uint8_t[getGlyphPageSize() * getGlyphPageSize() *
(CVS->isARBTextureSwizzleUsable() ? 1 : 4)]();
#else
uint8_t* data = NULL;
#endif
m_current_height = 0; m_current_height = 0;
m_used_width = 0; m_used_width = 0;
m_used_height = 0; m_used_height = 0;
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
// Font textures can not be resized (besides the impact on quality in StringUtils::toString(m_spritebank->getTextureCount()),
// this case, the rectangles in spritebank would become wrong). getGlyphPageSize(),
core::dimension2du old_max_size = irr_driver->getVideoDriver() #ifndef SERVER_ONLY
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE"); CVS->isARBTextureSwizzleUsable()
irr_driver->getVideoDriver()->getNonConstDriverAttributes() #else
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0)); false
#endif
video::ITexture* page_texture = irr_driver->getVideoDriver() );
->addTexture("Glyph_page", m_page); m_spritebank->addTexture(stkt);
m_spritebank->addTexture(NULL); STKTexManager::getInstance()->addTexture(stkt);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
// Doing so to make sure the texture inside the sprite bank has only 1
// reference, so they can be removed or updated on-the-fly
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // createNewGlyphPage } // createNewGlyphPage
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -184,80 +181,17 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
"rendering a glyph to bitmap"); "rendering a glyph to bitmap");
// Convert to an anti-aliased bitmap // Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap; FT_Bitmap* bits = &(slot->bitmap);
core::dimension2du texture_size(bits->width + 1, bits->rows + 1);
core::dimension2du d(bits.width + 1, bits.rows + 1);
core::dimension2du texture_size;
texture_size = d.getOptimalSize(!(irr_driver->getVideoDriver()
->queryFeature(video::EVDF_TEXTURE_NPOT)), !(irr_driver
->getVideoDriver()->queryFeature(video::EVDF_TEXTURE_NSQUARE)),
true, 0);
if ((m_used_width + texture_size.Width > getGlyphPageSize() && if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
m_used_height + m_current_height + texture_size.Height > m_used_height + m_current_height + texture_size.Height >
getGlyphPageSize()) || getGlyphPageSize()) ||
m_used_height + texture_size.Height > getGlyphPageSize()) m_used_height + texture_size.Height > getGlyphPageSize())
{ {
// Current glyph page is full: // Add a new glyph page if current one is full
// Save the old glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d
("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
// Clear and add a new one
createNewGlyphPage(); createNewGlyphPage();
} }
video::IImage* glyph = NULL;
switch (bits.pixel_mode)
{
case FT_PIXEL_MODE_GRAY:
{
// Create our blank image.
glyph = irr_driver->getVideoDriver()
->createImage(video::ECF_A8R8G8B8, texture_size);
glyph->fill(video::SColor(0, 255, 255, 255));
// Load the grayscale data in.
const float gray_count = static_cast<float>(bits.num_grays);
const unsigned int image_pitch =
glyph->getPitch() / sizeof(unsigned int);
unsigned int* image_data = (unsigned int*)glyph->lock();
unsigned char* glyph_data = bits.buffer;
for (unsigned int y = 0; y < (unsigned int)bits.rows; y++)
{
unsigned char* row = glyph_data;
for (unsigned int x = 0; x < (unsigned)bits.width; x++)
{
image_data[y * image_pitch + x] |=
static_cast<unsigned int>(255.0f *
(static_cast<float>(*row++) / gray_count)) << 24;
}
glyph_data += bits.pitch;
}
glyph->unlock();
break;
}
default:
assert(false);
}
if (!glyph)
Log::fatal("FontWithFace", "Failed to load a glyph");
// Done creating a single glyph, now copy to the glyph page...
// Determine the linebreak location // Determine the linebreak location
if (m_used_width + texture_size.Width > getGlyphPageSize()) if (m_used_width + texture_size.Width > getGlyphPageSize())
{ {
@ -266,16 +200,39 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
m_current_height = 0; m_current_height = 0;
} }
// Copy to the full glyph page const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
glyph->copyTo(m_page, core::position2di(m_used_width, m_used_height)); #ifndef SERVER_ONLY
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
assert(bits->pixel_mode == FT_PIXEL_MODE_GRAY);
if (CVS->isARBTextureSwizzleUsable())
{
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
bits->width, bits->rows, GL_RED, GL_UNSIGNED_BYTE, bits->buffer);
}
else
{
const unsigned int size = bits->width * bits->rows;
uint8_t* image_data = new uint8_t[size * 4];
memset(image_data, 255, size * 4);
for (unsigned int i = 0; i < size; i++)
image_data[4 * i + 3] = bits->buffer[i];
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
bits->width, bits->rows, GL_BGRA, GL_UNSIGNED_BYTE, image_data);
delete[] image_data;
}
if (tex->hasMipMaps())
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
#endif
// Store the rectangle of current glyph // Store the rectangle of current glyph
gui::SGUISpriteFrame f; gui::SGUISpriteFrame f;
gui::SGUISprite s; gui::SGUISprite s;
core::rect<s32> rectangle(m_used_width, m_used_height, core::rect<s32> rectangle(m_used_width, m_used_height,
m_used_width + bits.width, m_used_height + bits.rows); m_used_width + bits->width, m_used_height + bits->rows);
f.rectNumber = m_spritebank->getPositions().size(); f.rectNumber = m_spritebank->getPositions().size();
f.textureNumber = m_spritebank->getTextureCount() - 1; f.textureNumber = cur_tex;
// Add frame to sprite // Add frame to sprite
s.Frames.push_back(f); s.Frames.push_back(f);
@ -295,10 +252,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
a.spriteno = f.rectNumber; a.spriteno = f.rectNumber;
m_character_area_map[c] = a; m_character_area_map[c] = a;
// Clean the temporary glyph
glyph->drop();
glyph = NULL;
// Store used area // Store used area
m_used_width += texture_size.Width; m_used_width += texture_size.Width;
if (m_current_height < texture_size.Height) if (m_current_height < texture_size.Height)
@ -321,23 +274,6 @@ void FontWithFace::updateCharactersList()
} }
m_new_char_holder.clear(); m_new_char_holder.clear();
// Update last glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // updateCharactersList } // updateCharactersList
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -353,10 +289,9 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
core::dimension2d<u32> size = tex->getSize(); core::dimension2d<u32> size = tex->getSize();
video::ECOLOR_FORMAT col_format = tex->getColorFormat(); video::ECOLOR_FORMAT col_format = tex->getColorFormat();
void* data = tex->lock(); void* data = tex->lock();
video::IImage* image = irr_driver->getVideoDriver() video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(col_format, size, data, false/*copy mem*/); ->createImageFromData(col_format, size, data,
true/*ownForeignMemory*/);
tex->unlock(); tex->unlock();
irr_driver->getVideoDriver()->writeImageToFile(image, std::string irr_driver->getVideoDriver()->writeImageToFile(image, std::string
(name + "_" + StringUtils::toString(i) + ".png").c_str()); (name + "_" + StringUtils::toString(i) + ".png").c_str());
@ -618,28 +553,6 @@ void FontWithFace::render(const core::stringw& text,
} }
else else
{ {
// Prevent overwriting texture used by billboard text when
// using lazy loading characters
if (supportLazyLoadChar() && fallback[i])
{
const int cur_texno = m_fallback_font->getSpriteBank()
->getSprites()[area.spriteno].Frames[0].textureNumber;
if (cur_texno == int(m_fallback_font->getSpriteBank()
->getTextureCount() - 1))
{
m_fallback_font->createNewGlyphPage();
}
}
else if (supportLazyLoadChar())
{
const int cur_texno = m_spritebank
->getSprites()[area.spriteno].Frames[0].textureNumber;
if (cur_texno == int(m_spritebank->getTextureCount() - 1))
{
createNewGlyphPage();
}
}
// Billboard text specific, use offset_y_bt instead // Billboard text specific, use offset_y_bt instead
float glyph_offset_x = area.bearing_x * float glyph_offset_x = area.bearing_x *
(fallback[i] ? m_fallback_font_scale : scale); (fallback[i] ? m_fallback_font_scale : scale);

View File

@ -92,6 +92,39 @@ protected:
/** Used in top side bearing calculation. */ /** Used in top side bearing calculation. */
int m_glyph_max_height; int m_glyph_max_height;
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Set the fallback font for this font, so if some character is missing in /** Set the fallback font for this font, so if some character is missing in
* this font, it will use that fallback font to try rendering it. * this font, it will use that fallback font to try rendering it.
@ -129,9 +162,6 @@ private:
/** Sprite bank to store each glyph. */ /** Sprite bank to store each glyph. */
gui::IGUISpriteBank* m_spritebank; gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font. */
video::IImage* m_page;
/** The current max height at current drawing line in glyph page. */ /** The current max height at current drawing line in glyph page. */
unsigned int m_current_height; unsigned int m_current_height;
@ -206,6 +236,8 @@ private:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void loadGlyphInfo(wchar_t c); void loadGlyphInfo(wchar_t c);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
/** Add a character into \ref m_new_char_holder for lazy loading later. */ /** Add a character into \ref m_new_char_holder for lazy loading later. */
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); } void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -213,6 +245,9 @@ private:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setDPI(); void setDPI();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Defined by sub-class about the texture size of glyph page, it should be /** Defined by sub-class about the texture size of glyph page, it should be
* a power of two. */ * a power of two. */
virtual unsigned int getGlyphPageSize() const = 0; virtual unsigned int getGlyphPageSize() const = 0;
@ -266,44 +301,6 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Return the dpi of this face. */ /** Return the dpi of this face. */
unsigned int getDPI() const { return m_face_dpi; } unsigned int getDPI() const { return m_face_dpi; }
// ------------------------------------------------------------------------
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
void createNewGlyphPage();
}; // FontWithFace }; // FontWithFace

View File

@ -24,18 +24,9 @@
#include "graphics/shader.hpp" #include "graphics/shader.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/shared_gpu_objects.hpp" #include "graphics/shared_gpu_objects.hpp"
#include "graphics/texture_manager.hpp"
#include "graphics/texture_shader.hpp" #include "graphics/texture_shader.hpp"
#include "utils/cpp2011.hpp" #include "utils/cpp2011.hpp"
#if defined(USE_GLES2)
# define _IRR_COMPILE_WITH_OGLES2_
# include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h"
#else
# include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
#endif
// ============================================================================ // ============================================================================
class Primitive2DList : public TextureShader<Primitive2DList, 1, float> class Primitive2DList : public TextureShader<Primitive2DList, 1, float>
{ {
@ -186,16 +177,8 @@ static void drawTexColoredQuad(const video::ITexture *texture,
ColoredTextureRectShader::getInstance()->use(); ColoredTextureRectShader::getInstance()->use();
glBindVertexArray(ColoredTextureRectShader::getInstance()->m_vao); glBindVertexArray(ColoredTextureRectShader::getInstance()->m_vao);
#if !defined(USE_GLES2)
const irr::video::COpenGLTexture *t =
static_cast<const irr::video::COpenGLTexture*>(texture);
#else
const irr::video::COGLES2Texture *t =
static_cast<const irr::video::COGLES2Texture*>(texture);
#endif
ColoredTextureRectShader::getInstance() ColoredTextureRectShader::getInstance()
->setTextureUnits(t->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
ColoredTextureRectShader::getInstance() ColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
core::vector2df(width, height), core::vector2df(width, height),
@ -367,16 +350,8 @@ void draw2DImage(const video::ITexture* texture,
UniformColoredTextureRectShader::getInstance()->use(); UniformColoredTextureRectShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getUI_VAO()); glBindVertexArray(SharedGPUObjects::getUI_VAO());
#if !defined(USE_GLES2)
const video::COpenGLTexture *c_texture =
static_cast<const video::COpenGLTexture*>(texture);
#else
const video::COGLES2Texture *c_texture =
static_cast<const video::COGLES2Texture*>(texture);
#endif
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setTextureUnits(c_texture->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
@ -450,16 +425,8 @@ void draw2DImage(const video::ITexture* texture,
UniformColoredTextureRectShader::getInstance()->use(); UniformColoredTextureRectShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getUI_VAO()); glBindVertexArray(SharedGPUObjects::getUI_VAO());
#if !defined(USE_GLES2)
const video::COpenGLTexture *c_texture =
static_cast<const video::COpenGLTexture*>(texture);
#else
const video::COGLES2Texture *c_texture =
static_cast<const video::COGLES2Texture*>(texture);
#endif
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setTextureUnits(c_texture->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
@ -574,14 +541,7 @@ void draw2DImage(const video::ITexture* texture,
} }
else else
{ {
#if !defined(USE_GLES2) drawTexQuad(texture->getOpenGLTextureName(), width, height,
const video::COpenGLTexture *c_texture =
static_cast<const video::COpenGLTexture*>(texture);
#else
const video::COGLES2Texture *c_texture =
static_cast<const video::COGLES2Texture*>(texture);
#endif
drawTexQuad(c_texture->getOpenGLTextureName(), width, height,
center_pos_x, center_pos_y, tex_center_pos_x, center_pos_x, center_pos_y, tex_center_pos_x,
tex_center_pos_y, tex_width, tex_height); tex_center_pos_y, tex_width, tex_height);
} }
@ -657,14 +617,7 @@ void draw2DImage(const video::ITexture* texture,
} }
else else
{ {
#if !defined(USE_GLES2) drawTexQuad(texture->getOpenGLTextureName(), width, height,
const video::COpenGLTexture *c_texture =
static_cast<const video::COpenGLTexture*>(texture);
#else
const video::COGLES2Texture *c_texture =
static_cast<const video::COGLES2Texture*>(texture);
#endif
drawTexQuad(c_texture->getOpenGLTextureName(), width, height,
center_pos_x, center_pos_y, tex_center_pos_x, center_pos_x, center_pos_y, tex_center_pos_x,
tex_center_pos_y, tex_width, tex_height); tex_center_pos_y, tex_width, tex_height);
} }
@ -707,8 +660,7 @@ void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices,
Primitive2DList::getInstance()->use(); Primitive2DList::getInstance()->use();
Primitive2DList::getInstance()->setUniforms(1.0f); Primitive2DList::getInstance()->setUniforms(1.0f);
compressTexture(tex, false); Primitive2DList::getInstance()->setTextureUnits(tex->getOpenGLTextureName());
Primitive2DList::getInstance()->setTextureUnits(getTextureGLuint(tex));
glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0);
glDeleteVertexArrays(1, &tmpvao); glDeleteVertexArrays(1, &tmpvao);

View File

@ -51,6 +51,7 @@ void CentralVideoSettings::init()
hasExplicitAttribLocation = false; hasExplicitAttribLocation = false;
hasGS = false; hasGS = false;
hasTextureFilterAnisotropic = false; hasTextureFilterAnisotropic = false;
hasTextureSwizzle = false;
#if defined(USE_GLES2) #if defined(USE_GLES2)
hasBGRA = false; hasBGRA = false;
@ -163,9 +164,12 @@ void CentralVideoSettings::init()
Log::info("GLDriver", "ARB Multi Draw Indirect Present"); Log::info("GLDriver", "ARB Multi Draw Indirect Present");
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) && if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
hasGLExtension("GL_EXT_texture_compression_s3tc")) { hasGLExtension("GL_EXT_texture_compression_s3tc") &&
hasGLExtension("GL_ARB_texture_compression_rgtc"))
{
hasTextureCompression = true; hasTextureCompression = true;
Log::info("GLDriver", "EXT Texture Compression S3TC Present"); Log::info("GLDriver", "EXT Texture Compression S3TC Present");
Log::info("GLDriver", "ARB Texture Compression RGTC Present");
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) && if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
hasGLExtension("GL_ARB_uniform_buffer_object")) { hasGLExtension("GL_ARB_uniform_buffer_object")) {
@ -187,7 +191,11 @@ void CentralVideoSettings::init()
hasGS = true; hasGS = true;
Log::info("GLDriver", "Geometry Shaders Present"); Log::info("GLDriver", "Geometry Shaders Present");
} }
if (hasGLExtension("GL_ARB_texture_swizzle"))
{
hasTextureSwizzle = true;
Log::info("GLDriver", "ARB Texture Swizzle Present");
}
// Only unset the high def textures if they are set as default. If the // Only unset the high def textures if they are set as default. If the
// user has enabled them (bit 1 set), then leave them enabled. // user has enabled them (bit 1 set), then leave them enabled.
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) && if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
@ -228,6 +236,7 @@ void CentralVideoSettings::init()
if (m_glsl == true) if (m_glsl == true)
{ {
hasTextureStorage = true; hasTextureStorage = true;
hasTextureSwizzle = true;
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) && if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
@ -447,4 +456,10 @@ bool CentralVideoSettings::supportsHardwareSkinning() const
{ {
return isARBUniformBufferObjectUsable(); return isARBUniformBufferObjectUsable();
} }
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
{
return m_glsl && hasTextureSwizzle;
}
#endif // !SERVER_ONLY #endif // !SERVER_ONLY

View File

@ -43,6 +43,7 @@ private:
bool hasImageLoadStore; bool hasImageLoadStore;
bool hasMultiDrawIndirect; bool hasMultiDrawIndirect;
bool hasTextureFilterAnisotropic; bool hasTextureFilterAnisotropic;
bool hasTextureSwizzle;
#if defined(USE_GLES2) #if defined(USE_GLES2)
bool hasBGRA; bool hasBGRA;
@ -82,6 +83,7 @@ public:
bool isARBMultiDrawIndirectUsable() const; bool isARBMultiDrawIndirectUsable() const;
bool isARBExplicitAttribLocationUsable() const; bool isARBExplicitAttribLocationUsable() const;
bool isEXTTextureFilterAnisotropicUsable() const; bool isEXTTextureFilterAnisotropicUsable() const;
bool isARBTextureSwizzleUsable() const;
#if defined(USE_GLES2) #if defined(USE_GLES2)
bool isEXTTextureFormatBGRA8888Usable() const; bool isEXTTextureFormatBGRA8888Usable() const;

View File

@ -21,7 +21,6 @@
#include "graphics/shader.hpp" #include "graphics/shader.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_mesh.hpp" #include "graphics/stk_mesh.hpp"
#include "graphics/texture_manager.hpp"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Variadic template to draw a mesh (using OpenGL 3.2 function) /** Variadic template to draw a mesh (using OpenGL 3.2 function)
@ -87,10 +86,8 @@ struct TexExpanderImpl
Args... args) Args... args)
{ {
size_t idx = STK::tuple_get<sizeof...(TupleArgs) - N>(tex_swizzle); size_t idx = STK::tuple_get<sizeof...(TupleArgs) - N>(tex_swizzle);
TexExpanderImpl<T, N - 1>::template expandTex( mesh, TexExpanderImpl<T, N - 1>::template expandTex(mesh, tex_swizzle,
tex_swizzle, args..., mesh.textures[idx]->getOpenGLTextureName());
args...,
getTextureGLuint(mesh.textures[idx]));
} // ExpandTex } // ExpandTex
}; // TexExpanderImpl }; // TexExpanderImpl

View File

@ -222,7 +222,10 @@ void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits,
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]); Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]);
else else
Shader::getInstance()->setTextureUnits(getTextureGLuint(mesh.textures[0])); {
Shader::getInstance()->setTextureUnits(mesh.textures[0]
->getOpenGLTextureName());
}
CustomUnrollArgs<List...>::template drawMesh<Shader>(meshes->at(i)); CustomUnrollArgs<List...>::template drawMesh<Shader>(meshes->at(i));
} }
} // renderTransparenPass } // renderTransparenPass
@ -370,10 +373,10 @@ void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls,
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
// Render the effect // Render the effect
DisplaceShader::getInstance()->setTextureUnits( DisplaceShader::getInstance()->setTextureUnits(
getTextureGLuint(m_displace_tex), m_displace_tex->getOpenGLTextureName(),
colors_framebuffer.getRTT()[0], colors_framebuffer.getRTT()[0],
tmp_framebuffer.getRTT()[0], tmp_framebuffer.getRTT()[0],
getTextureGLuint(mesh.textures[0])); mesh.textures[0]->getOpenGLTextureName());
DisplaceShader::getInstance()->use(); DisplaceShader::getInstance()->use();
DisplaceShader::getInstance()->setUniforms(AbsoluteTransformation, DisplaceShader::getInstance()->setUniforms(AbsoluteTransformation,
core::vector2df(cb->getDirX(), cb->getDirY()), core::vector2df(cb->getDirX(), cb->getDirY()),

View File

@ -23,7 +23,6 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/particle_emitter.hpp" #include "graphics/particle_emitter.hpp"
#include "graphics/shared_gpu_objects.hpp" #include "graphics/shared_gpu_objects.hpp"
#include "graphics/texture_manager.hpp"
#include "graphics/texture_shader.hpp" #include "graphics/texture_shader.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
@ -158,7 +157,7 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter,
track_z = 0; track_z = 0;
track_x_len = 0; track_x_len = 0;
track_z_len = 0; track_z_len = 0;
texture = 0; m_texture_name = 0;
} }
ParticleSystemProxy::~ParticleSystemProxy() ParticleSystemProxy::~ParticleSystemProxy()
@ -394,9 +393,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
assert(0 && "Wrong particle type"); assert(0 && "Wrong particle type");
} }
video::ITexture *tex = getMaterial(0).getTexture(0); m_texture_name = getMaterial(0).getTexture(0)->getOpenGLTextureName();
compressTexture(tex, true, true);
texture = getTextureGLuint(getMaterial(0).getTexture(0));
} }
void ParticleSystemProxy::cleanGL() void ParticleSystemProxy::cleanGL()
@ -528,7 +525,7 @@ void ParticleSystemProxy::drawFlip()
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
FlipParticleRender::getInstance()->use(); FlipParticleRender::getInstance()->use();
FlipParticleRender::getInstance()->setTextureUnits(texture, irr_driver->getDepthStencilTexture()); FlipParticleRender::getInstance()->setTextureUnits(m_texture_name, irr_driver->getDepthStencilTexture());
FlipParticleRender::getInstance()->setUniforms(); FlipParticleRender::getInstance()->setUniforms();
glBindVertexArray(current_rendering_vao); glBindVertexArray(current_rendering_vao);
@ -543,7 +540,7 @@ void ParticleSystemProxy::drawNotFlip()
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
SimpleParticleRender::getInstance()->use(); SimpleParticleRender::getInstance()->use();
SimpleParticleRender::getInstance()->setTextureUnits(texture, irr_driver->getDepthStencilTexture()); SimpleParticleRender::getInstance()->setTextureUnits(m_texture_name, irr_driver->getDepthStencilTexture());
video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]); video::SColorf ColorFrom = video::SColorf(getColorFrom()[0], getColorFrom()[1], getColorFrom()[2]);
video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]); video::SColorf ColorTo = video::SColorf(getColorTo()[0], getColorTo()[1], getColorTo()[2]);

View File

@ -43,7 +43,7 @@ protected:
bool m_first_execution; bool m_first_execution;
bool m_randomize_initial_y; bool m_randomize_initial_y;
GLuint texture; GLuint m_texture_name;
/** Previous frame particles emitter source matrix */ /** Previous frame particles emitter source matrix */
core::matrix4 m_previous_frame_matrix; core::matrix4 m_previous_frame_matrix;

View File

@ -36,9 +36,11 @@
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/stk_animated_mesh.hpp" #include "graphics/stk_animated_mesh.hpp"
#include "graphics/stk_billboard.hpp" #include "graphics/stk_billboard.hpp"
#include "graphics/stk_mesh_loader.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "graphics/stk_texture.hpp"
#include "graphics/sun.hpp" #include "graphics/sun.hpp"
#include "graphics/texture_manager.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/message_queue.hpp" #include "guiengine/message_queue.hpp"
#include "guiengine/modaldialog.hpp" #include "guiengine/modaldialog.hpp"
@ -65,12 +67,6 @@
#include "utils/vs.hpp" #include "utils/vs.hpp"
#include <irrlicht.h> #include <irrlicht.h>
#if defined(USE_GLES2)
#define _IRR_COMPILE_WITH_OGLES2_
#include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h"
#else
#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
#endif
/* Build-time check that the Irrlicht we're building against works for us. /* Build-time check that the Irrlicht we're building against works for us.
* Should help prevent distros building against an incompatible library. * Should help prevent distros building against an incompatible library.
@ -159,13 +155,10 @@ IrrDriver::IrrDriver()
IrrDriver::~IrrDriver() IrrDriver::~IrrDriver()
{ {
assert(m_device != NULL); assert(m_device != NULL);
#ifndef SERVER_ONLY
cleanUnicolorTextures();
#endif
m_device->drop(); m_device->drop();
m_device = NULL; m_device = NULL;
m_modes.clear(); m_modes.clear();
STKTexManager::getInstance()->kill();
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (CVS->isGLSL()) if (CVS->isGLSL())
{ {
@ -600,6 +593,9 @@ void IrrDriver::initDevice()
m_scene_manager = m_device->getSceneManager(); m_scene_manager = m_device->getSceneManager();
m_gui_env = m_device->getGUIEnvironment(); m_gui_env = m_device->getGUIEnvironment();
m_video_driver = m_device->getVideoDriver(); m_video_driver = m_device->getVideoDriver();
STKMeshLoader* sml = new STKMeshLoader(m_scene_manager);
m_scene_manager->addExternalMeshLoader(sml);
sml->drop();
m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize(); m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize();
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
@ -747,11 +743,11 @@ void IrrDriver::createSunInterposer()
if (!mb) if (!mb)
continue; continue;
mb->getMaterial().setTexture(0, mb->getMaterial().setTexture(0,
getUnicolorTexture(video::SColor(255, 255, 255, 255))); STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 255, 255)));
mb->getMaterial().setTexture(1, mb->getMaterial().setTexture(1,
getUnicolorTexture(video::SColor(0, 0, 0, 0))); STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
mb->getMaterial().setTexture(2, mb->getMaterial().setTexture(2,
getUnicolorTexture(video::SColor(0, 0, 0, 0))); STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
} }
m_sun_interposer = new STKMeshSceneNode(sphere, m_sun_interposer = new STKMeshSceneNode(sphere,
m_scene_manager->getRootSceneNode(), m_scene_manager->getRootSceneNode(),
@ -926,8 +922,7 @@ void IrrDriver::applyResolutionSettings()
// That's just error prone // That's just error prone
// (we're sure to update main.cpp at some point and forget this one...) // (we're sure to update main.cpp at some point and forget this one...)
VAOManager::getInstance()->kill(); VAOManager::getInstance()->kill();
resetTextureTable(); STKTexManager::getInstance()->kill();
cleanUnicolorTextures();
// initDevice will drop the current device. // initDevice will drop the current device.
if (CVS->isGLSL()) if (CVS->isGLSL())
{ {
@ -942,6 +937,7 @@ void IrrDriver::applyResolutionSettings()
// Re-init GUI engine // Re-init GUI engine
GUIEngine::init(m_device, m_video_driver, StateManager::get()); GUIEngine::init(m_device, m_video_driver, StateManager::get());
setMaxTextureSize();
//material_manager->reInit(); //material_manager->reInit();
material_manager = new MaterialManager(); material_manager = new MaterialManager();
material_manager->loadMaterial(); material_manager->loadMaterial();
@ -955,7 +951,7 @@ void IrrDriver::applyResolutionSettings()
->getAsset(FileManager::GUI,"options_video.png")) ->getAsset(FileManager::GUI,"options_video.png"))
); );
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,"")); file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""), "models");
const std::string materials_file = const std::string materials_file =
file_manager->getAssetChecked(FileManager::MODEL, "materials.xml"); file_manager->getAssetChecked(FileManager::MODEL, "materials.xml");
if (materials_file != "") if (materials_file != "")
@ -1198,10 +1194,10 @@ scene::IMeshSceneNode *IrrDriver::addSphere(float radius,
m.BackfaceCulling = false; m.BackfaceCulling = false;
m.MaterialType = video::EMT_SOLID; m.MaterialType = video::EMT_SOLID;
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
//m.setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180))); //m.setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180)));
m.setTexture(0, getUnicolorTexture(color)); m.setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(color));
m.setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m.setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
m.setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m.setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
if (CVS->isGLSL()) if (CVS->isGLSL())
{ {
@ -1429,6 +1425,12 @@ void IrrDriver::removeMeshFromCache(scene::IMesh *mesh)
*/ */
void IrrDriver::removeTexture(video::ITexture *t) void IrrDriver::removeTexture(video::ITexture *t)
{ {
STKTexture* stkt = dynamic_cast<STKTexture*>(t);
if (stkt)
{
STKTexManager::getInstance()->removeTexture(stkt);
return;
}
m_video_driver->removeTexture(t); m_video_driver->removeTexture(t);
} // removeTexture } // removeTexture
@ -1569,6 +1571,7 @@ void IrrDriver::unsetTextureErrorMessage()
} // unsetTextureErrorMessage } // unsetTextureErrorMessage
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if 0
/** Retrieve all textures in the specified directory, generate a smaller /** Retrieve all textures in the specified directory, generate a smaller
* version for each of them and save them in the cache. Smaller textures are * version for each of them and save them in the cache. Smaller textures are
* generated only if they do not already exist or if their original version * generated only if they do not already exist or if their original version
@ -1635,7 +1638,7 @@ std::string IrrDriver::getSmallerTexture(const std::string& filename)
} // if !file_manager->fileExists(cached_file) } // if !file_manager->fileExists(cached_file)
return cached_file; return cached_file;
} // getSmallerTexture } // getSmallerTexture
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Loads a texture from a file and returns the texture object. This is just /** Loads a texture from a file and returns the texture object. This is just
* a convenient wrapper which loads the texture from a STK asset directory. * a convenient wrapper which loads the texture from a STK asset directory.
@ -1671,110 +1674,9 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
bool is_prediv, bool is_prediv,
bool complain_if_not_found) bool complain_if_not_found)
{ {
video::ITexture* out; return STKTexManager::getInstance()->getTexture(filename);
if(!is_premul && !is_prediv)
{
if (!complain_if_not_found) m_device->getLogger()->setLogLevel(ELL_NONE);
out = m_video_driver->getTexture(filename.c_str());
if (!complain_if_not_found) m_device->getLogger()->setLogLevel(ELL_WARNING);
}
else
{
// FIXME: can't we just do this externally, and just use the
// modified textures??
video::IImage* img =
m_video_driver->createImageFromFile(filename.c_str());
// PNGs are non premul, but some are used for premul tasks, so convert
// http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Premultiplied%20alpha]]
// FIXME check param, not name
if(img && is_premul &&
StringUtils::hasSuffix(filename.c_str(), ".png") &&
(img->getColorFormat() == video::ECF_A8R8G8B8) &&
img->lock())
{
core::dimension2d<u32> dim = img->getDimension();
for(unsigned int x = 0; x < dim.Width; x++)
{
for(unsigned int y = 0; y < dim.Height; y++)
{
video::SColor col = img->getPixel(x, y);
unsigned int alpha = col.getAlpha();
unsigned int red = alpha * col.getRed() / 255;
unsigned int blue = alpha * col.getBlue() / 255;
unsigned int green = alpha * col.getGreen() / 255;
col.set(alpha, red, green, blue);
img->setPixel(x, y, col, false);
} // for y
} // for x
img->unlock();
} // if png and ColorFOrmat and lock
// Other formats can be premul, but the tasks can be non premul
// So divide to get the separate RGBA (only possible if alpha!=0)
else if(img && is_prediv &&
(img->getColorFormat() == video::ECF_A8R8G8B8) &&
img->lock())
{
core::dimension2d<u32> dim = img->getDimension();
for(unsigned int x = 0; x < dim.Width; x++)
{
for(unsigned int y = 0; y < dim.Height; y++)
{
video::SColor col = img->getPixel(x, y);
unsigned int alpha = col.getAlpha();
// Avoid divide by zero
if (alpha) {
unsigned int red = 255 * col.getRed() / alpha ;
unsigned int blue = 255 * col.getBlue() / alpha;
unsigned int green = 255 * col.getGreen() / alpha;
col.set(alpha, red, green, blue);
img->setPixel(x, y, col, false);
}
} // for y
} // for x
img->unlock();
} // if premul && color format && lock
out = m_video_driver->addTexture(filename.c_str(), img, NULL);
} // if is_premul or is_prediv
if (complain_if_not_found && out == NULL)
{
if(m_texture_error_message.size()>0)
{
Log::error("irr_driver", m_texture_error_message.c_str());
}
Log::error("irr_driver", "Texture '%s' not found.", filename.c_str());
}
m_texturesFileName[out] = filename;
return out;
} // getTexture } // getTexture
// ----------------------------------------------------------------------------
/** Clear the texture-filename reminder.
*/
void IrrDriver::clearTexturesFileName()
{
m_texturesFileName.clear();
} // clearTexturesFileName
// ----------------------------------------------------------------------------
/** Get the texture file name using a texture pointer.
* \param tex Pointer on the texture for which we want to find the file name.
* \return Filename of the texture if found, or an empty string otherwise.
*/
std::string IrrDriver::getTextureName(video::ITexture* tex)
{
std::map<video::ITexture*, std::string>::iterator it;
it = m_texturesFileName.find(tex);
if (it != m_texturesFileName.end())
return it->second;
else
return "";
} // getTextureName
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Appends a pointer to each texture used in this mesh to the vector. /** Appends a pointer to each texture used in this mesh to the vector.
* \param mesh The mesh from which the textures are being determined. * \param mesh The mesh from which the textures are being determined.
@ -1823,76 +1725,6 @@ void IrrDriver::dropAllTextures(const scene::IMesh *mesh)
} // for i <getMeshBufferCount } // for i <getMeshBufferCount
} // dropAllTextures } // dropAllTextures
// ----------------------------------------------------------------------------
void IrrDriver::applyMask(video::ITexture* texture,
const std::string& mask_path)
{
#ifndef SERVER_ONLY
const core::dimension2d<u32> size = texture->getSize();
video::IImage* img =
m_video_driver->createImage(texture, core::position2d<s32>(0,0), size);
video::IImage* mask =
m_video_driver->createImageFromFile(mask_path.c_str());
if (img == NULL || mask == NULL)
{
Log::warn("irr_driver", "Applying mask failed for '%s'!",
texture->getName().getPtr());
return;
}
if (mask->getDimension() != size)
{
video::IImage* mask_scaled =
m_video_driver->createImage(texture->getColorFormat(), size);
mask->copyToScaling(mask_scaled);
mask->drop();
mask = mask_scaled;
}
void* dest = img->lock();
if (dest != NULL && mask->lock())
{
core::dimension2d<u32> dim = img->getDimension();
for (unsigned int x = 0; x < dim.Width; x++)
{
for (unsigned int y = 0; y < dim.Height; y++)
{
video::SColor col = img->getPixel(x, y);
video::SColor alpha = mask->getPixel(x, y);
col.setAlpha( alpha.getRed() );
img->setPixel(x, y, col, false);
} // for y
} // for x
if (!CVS->isGLSL())
{
// For new graphical pipeline, it will be done in texture manager
// compressTexture
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(texture));
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dim.Width, dim.Height,
GL_BGRA, GL_UNSIGNED_BYTE, dest);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
mask->unlock();
img->unlock();
#if defined(USE_GLES2)
static_cast<irr::video::COGLES2Texture*>(texture)->setImage(img);
#else
static_cast<irr::video::COpenGLTexture*>(texture)->setImage(img);
#endif
mask->drop();
return;
}
Log::warn("irr_driver", "Applying mask failed for '%s'!",
texture->getName().getPtr());
img->drop();
mask->drop();
#endif
} // applyMask
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void IrrDriver::onLoadWorld() void IrrDriver::onLoadWorld()
{ {

View File

@ -111,10 +111,6 @@ private:
private: private:
/** Keep a trace of the origin file name of a texture. */
std::map<video::ITexture*, std::string> m_texturesFileName;
/** Flag to indicate if a resolution change is pending (which will be /** Flag to indicate if a resolution change is pending (which will be
* acted upon in the next update). None means no change, yes means * acted upon in the next update). None means no change, yes means
* change to new resolution and trigger confirmation dialog. * change to new resolution and trigger confirmation dialog.
@ -220,14 +216,14 @@ public:
void setAllMaterialFlags(scene::IMesh *mesh) const; void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name); scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name); scene::IMesh *getMesh(const std::string &name);
void applyMask(video::ITexture* texture,
const std::string& mask_path);
void displayFPS(); void displayFPS();
bool OnEvent(const irr::SEvent &event); bool OnEvent(const irr::SEvent &event);
void setAmbientLight(const video::SColorf &light, void setAmbientLight(const video::SColorf &light,
bool force_SH_computation = true); bool force_SH_computation = true);
#if 0
std::string generateSmallerTextures(const std::string& dir); std::string generateSmallerTextures(const std::string& dir);
std::string getSmallerTexture(const std::string& texture); std::string getSmallerTexture(const std::string& texture);
#endif
video::ITexture *getTexture(FileManager::AssetType type, video::ITexture *getTexture(FileManager::AssetType type,
const std::string &filename, const std::string &filename,
bool is_premul=false, bool is_premul=false,
@ -237,8 +233,6 @@ public:
bool is_premul=false, bool is_premul=false,
bool is_prediv=false, bool is_prediv=false,
bool complain_if_not_found=true); bool complain_if_not_found=true);
void clearTexturesFileName();
std::string getTextureName(video::ITexture* tex);
void grabAllTextures(const scene::IMesh *mesh); void grabAllTextures(const scene::IMesh *mesh);
void dropAllTextures(const scene::IMesh *mesh); void dropAllTextures(const scene::IMesh *mesh);
scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL, scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL,

View File

@ -33,7 +33,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
@ -399,12 +399,11 @@ Material::Material(const XMLNode *node, bool deprecated)
m_high_tire_adhesion = true; m_high_tire_adhesion = true;
} // Material } // Material
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
video::ITexture* Material::getTexture(bool srgb, bool premul_alpha)
video::ITexture* Material::getTexture()
{ {
if (!m_installed) if (!m_installed)
{ {
install(); install(srgb, premul_alpha);
} }
return m_texture; return m_texture;
} // getTexture } // getTexture
@ -489,25 +488,27 @@ void Material::init()
} // init } // init
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Material::install() void Material::install(bool srgb, bool premul_alpha)
{ {
// Don't load a texture that are not supposed to be loaded automatically // Don't load a texture that are not supposed to be loaded automatically
if (m_installed) return; if (m_installed) return;
m_installed = true; m_installed = true;
if (m_complain_if_not_found && m_full_path.size() == 0) if (m_texname.find(".") == std::string::npos || m_full_path.empty())
{ {
Log::error("material", "Cannot find texture '%s'.", m_texname.c_str()); if (m_complain_if_not_found)
{
Log::error("material", "Cannot find texture '%s'.",
m_texname.c_str());
}
m_texture = NULL; m_texture = NULL;
} }
else else
{ {
m_texture = irr_driver->getTexture(m_full_path, m_texture = STKTexManager::getInstance()->getTexture
false, //isPreMul(), (m_full_path, srgb, premul_alpha, false/*set_material*/,
false, //isPreDiv(), srgb/*mesh_tex*/);
m_complain_if_not_found);
} }
if (m_texture == NULL) return; if (m_texture == NULL) return;
@ -515,10 +516,6 @@ void Material::install()
// now set the name to the basename, so that all tests work as expected // now set the name to the basename, so that all tests work as expected
m_texname = StringUtils::getBasename(m_texname); m_texname = StringUtils::getBasename(m_texname);
if (m_mask.size() > 0)
{
irr_driver->applyMask(m_texture, m_mask);
}
m_texture->grab(); m_texture->grab();
} // install } // install
@ -747,22 +744,28 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
{ {
ITexture *tex; ITexture *tex;
ITexture *glossytex; ITexture *glossytex;
STKTexManager* stm = STKTexManager::getInstance();
if (m_gloss_map.size() > 0 && UserConfigParams::m_dynamic_lights) if (m_gloss_map.size() > 0 && UserConfigParams::m_dynamic_lights)
{ {
glossytex = irr_driver->getTexture(m_gloss_map); glossytex = stm->getTexture(m_gloss_map, false/*srgb*/,
false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
} }
else else
{ {
glossytex = getUnicolorTexture(SColor(0, 0, 0, 0)); glossytex = stm->STKTexManager::getInstance()->getUnicolorTexture(SColor(0, 0, 0, 0));
} }
if (!m->getTexture(2)) if (!m->getTexture(2))
{ {
// Only set colorization mask if not set // Only set colorization mask if not set
ITexture *colorization_mask_tex = getUnicolorTexture(SColor(0, 0, 0, 0)); ITexture *colorization_mask_tex =
stm->STKTexManager::getInstance()->getUnicolorTexture(SColor(0, 0, 0, 0));
if (m_colorization_mask.size() > 0) if (m_colorization_mask.size() > 0)
{ {
colorization_mask_tex = irr_driver->getTexture(m_colorization_mask); colorization_mask_tex = stm->getTexture(m_colorization_mask,
false/*srgb*/, false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/, false/*no_upload*/, true/*single_channel*/);
} }
m->setTexture(2, colorization_mask_tex); m->setTexture(2, colorization_mask_tex);
} }
@ -818,24 +821,32 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
m->setTexture(1, glossytex); m->setTexture(1, glossytex);
return; return;
case SHADERTYPE_SPLATTING: case SHADERTYPE_SPLATTING:
tex = irr_driver->getTexture(m_splatting_texture_1); tex = stm->getTexture(m_splatting_texture_1,
true/*srgb*/, false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
m->setTexture(3, tex); m->setTexture(3, tex);
if (m_splatting_texture_2.size() > 0) if (m_splatting_texture_2.size() > 0)
{ {
tex = irr_driver->getTexture(m_splatting_texture_2); tex = stm->getTexture(m_splatting_texture_2,
true/*srgb*/, false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
} }
m->setTexture(4, tex); m->setTexture(4, tex);
if (m_splatting_texture_3.size() > 0) if (m_splatting_texture_3.size() > 0)
{ {
tex = irr_driver->getTexture(m_splatting_texture_3); tex = stm->getTexture(m_splatting_texture_3,
true/*srgb*/, false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
} }
m->setTexture(5, tex); m->setTexture(5, tex);
if (m_splatting_texture_4.size() > 0) if (m_splatting_texture_4.size() > 0)
{ {
tex = irr_driver->getTexture(m_splatting_texture_4); tex = stm->getTexture(m_splatting_texture_4,
false/*srgb*/, false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
} }
m->setTexture(6, tex); m->setTexture(6, tex);
m->setTexture(7, glossytex); m->setTexture(7, glossytex);
@ -868,14 +879,21 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
} }
if (!m->getTexture(0)) if (!m->getTexture(0))
m->setTexture(0, getUnicolorTexture(SColor(255, 255, 255, 255))); {
m->setTexture(0,
stm->STKTexManager::getInstance()->getUnicolorTexture(SColor(255, 255, 255, 255)));
}
if (m_normal_map_tex.size() > 0) if (m_normal_map_tex.size() > 0)
{ {
if (UserConfigParams::m_dynamic_lights) if (UserConfigParams::m_dynamic_lights)
tex = irr_driver->getTexture(m_normal_map_tex); {
tex = stm->getTexture(m_normal_map_tex, false/*srgb*/,
false/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
}
else else
tex = getUnicolorTexture(SColor(0, 0, 0, 0)); tex = stm->STKTexManager::getInstance()->getUnicolorTexture(SColor(0, 0, 0, 0));
m->setTexture(3, tex); m->setTexture(3, tex);
// Material and shaders // Material and shaders
@ -891,7 +909,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
if (m->getTexture(1) != glossytex) if (m->getTexture(1) != glossytex)
m->setTexture(3, m->getTexture(1)); m->setTexture(3, m->getTexture(1));
if (!m->getTexture(3)) if (!m->getTexture(3))
m->setTexture(3, getUnicolorTexture(SColor(255, 255, 255, 255))); m->setTexture(3, stm->STKTexManager::getInstance()->getUnicolorTexture(SColor(255, 255, 255, 255)));
} }
m->setTexture(1, glossytex); m->setTexture(1, glossytex);
} }

View File

@ -267,7 +267,7 @@ private:
bool m_installed; bool m_installed;
void init (); void init ();
void install (); void install (bool srgb = false, bool premul_alpha = false);
void initCustomSFX(const XMLNode *sfx); void initCustomSFX(const XMLNode *sfx);
void initParticlesEffect(const XMLNode *node); void initParticlesEffect(const XMLNode *node);
@ -290,7 +290,7 @@ public:
void isInitiallyHidden(scene::IMeshBuffer* who); void isInitiallyHidden(scene::IMeshBuffer* who);
/** Returns the ITexture associated with this material. */ /** Returns the ITexture associated with this material. */
video::ITexture *getTexture(); video::ITexture *getTexture(bool srgb = true, bool premul_alpha = false);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isIgnore () const { return m_ignore; } bool isIgnore () const { return m_ignore; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -419,7 +419,8 @@ public:
/** True if this texture should have the U coordinates mirrored. */ /** True if this texture should have the U coordinates mirrored. */
char getMirrorAxisInReverse() const { return m_mirror_axis_when_reverse; } char getMirrorAxisInReverse() const { return m_mirror_axis_when_reverse; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
} ; const std::string getAlphaMask() const { return m_mask; }
};
#endif #endif

View File

@ -78,13 +78,8 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t,
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Material* MaterialManager::getMaterialFor(video::ITexture* t)
Material* MaterialManager::getMaterialFor(video::ITexture* t,
video::E_MATERIAL_TYPE material_type)
{ {
if (t == NULL)
return getDefaultMaterial(material_type);
core::stringc img_path = core::stringc(t->getName()); core::stringc img_path = core::stringc(t->getName());
img_path.make_lower(); img_path.make_lower();
@ -116,6 +111,19 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t,
} }
} // for i } // for i
} }
return NULL;
}
//-----------------------------------------------------------------------------
Material* MaterialManager::getMaterialFor(video::ITexture* t,
video::E_MATERIAL_TYPE material_type)
{
if (t == NULL)
return getDefaultMaterial(material_type);
Material* m = getMaterialFor(t);
if (m != NULL)
return m;
return getDefaultMaterial(material_type); return getDefaultMaterial(material_type);
} }

View File

@ -61,6 +61,7 @@ public:
scene::IMeshBuffer *mb); scene::IMeshBuffer *mb);
Material* getMaterialFor(video::ITexture* t, Material* getMaterialFor(video::ITexture* t,
video::E_MATERIAL_TYPE material_type); video::E_MATERIAL_TYPE material_type);
Material* getMaterialFor(video::ITexture* t);
void setAllMaterialFlags(video::ITexture* t, void setAllMaterialFlags(video::ITexture* t,
scene::IMeshBuffer *mb); scene::IMeshBuffer *mb);
void adjustForFog(video::ITexture* t, void adjustForFog(video::ITexture* t,

View File

@ -257,7 +257,7 @@ Material* ParticleKind::getMaterial() const
if (material_manager->hasMaterial(m_material_file)) if (material_manager->hasMaterial(m_material_file))
{ {
Material* material = material_manager->getMaterial(m_material_file); Material* material = material_manager->getMaterial(m_material_file);
if (material->getTexture() == NULL) if (material->getTexture(true/*srgb*/, true/*premul_alpha*/) == NULL)
{ {
throw std::runtime_error("[ParticleKind] Cannot locate file " + m_material_file); throw std::runtime_error("[ParticleKind] Cannot locate file " + m_material_file);
} }

View File

@ -31,7 +31,8 @@
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/shared_gpu_objects.hpp" #include "graphics/shared_gpu_objects.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_texture.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "graphics/weather.hpp" #include "graphics/weather.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
@ -380,7 +381,7 @@ public:
setTextureUnits(render_target_bloom_128, setTextureUnits(render_target_bloom_128,
render_target_bloom_256, render_target_bloom_256,
render_target_bloom_512, render_target_bloom_512,
getTextureGLuint(lensDustTex)); lensDustTex->getOpenGLTextureName());
drawFullScreenEffect(); drawFullScreenEffect();
} // render } // render
}; // BloomBlendShader }; // BloomBlendShader
@ -705,8 +706,7 @@ public:
GLuint rtt_mlaa_tmp) GLuint rtt_mlaa_tmp)
{ {
use(); use();
setTextureUnits(rtt_mlaa_tmp, setTextureUnits(rtt_mlaa_tmp, area_map->getOpenGLTextureName());
getTextureGLuint(area_map));
drawFullScreenEffect(pixel_size); drawFullScreenEffect(pixel_size);
} // render } // render
@ -771,18 +771,20 @@ PostProcessing::PostProcessing(IVideoDriver* video_driver)
{ {
m_material.TextureLayer[i].TextureWrapU = m_material.TextureLayer[i].TextureWrapU =
m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
} }
// Load the MLAA area map // Load the MLAA area map
io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()-> io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()->
createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33), createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33),
"AreaMap33", false); "AreaMap33", false);
if (!areamap) video::IImage* img = irr_driver->getVideoDriver()->createImageFromFile(areamap);
m_areamap = new STKTexture(img, "AreaMap33");
if (m_areamap->getOpenGLTextureName() == 0)
{ {
Log::fatal("postprocessing", "Failed to load the areamap"); Log::fatal("postprocessing", "Failed to load the areamap");
return; return;
} }
m_areamap = irr_driver->getVideoDriver()->getTexture(areamap); STKTexManager::getInstance()->addTexture(m_areamap);
areamap->drop(); areamap->drop();
} // PostProcessing } // PostProcessing

View File

@ -27,6 +27,7 @@
class FrameBuffer; class FrameBuffer;
class RTT; class RTT;
class STKTexture;
namespace irr namespace irr
{ {
@ -63,7 +64,7 @@ private:
* the vertex position, normal, and texture coordinate. */ * the vertex position, normal, and texture coordinate. */
std::vector<Quad> m_vertices; std::vector<Quad> m_vertices;
video::ITexture *m_areamap; STKTexture* m_areamap;
void setMotionBlurCenterY(const u32 num, const float y); void setMotionBlurCenterY(const u32 num, const float y);

View File

@ -35,7 +35,6 @@
#include "graphics/skybox.hpp" #include "graphics/skybox.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/spherical_harmonics.hpp" #include "graphics/spherical_harmonics.hpp"
#include "graphics/texture_manager.hpp"
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "items/powerup_manager.hpp" #include "items/powerup_manager.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
@ -67,30 +66,6 @@ void ShaderBasedRenderer::setRTT(RTT* rtts)
} }
} //setRTT } //setRTT
// ----------------------------------------------------------------------------
void ShaderBasedRenderer::compressPowerUpTextures()
{
for (unsigned i = 0; i < PowerupManager::POWERUP_MAX; i++)
{
scene::IMesh *mesh = powerup_manager->m_all_meshes[i];
if (!mesh)
continue;
for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(j);
if (!mb)
continue;
for (unsigned k = 0; k < 4; k++)
{
video::ITexture *tex = mb->getMaterial().getTexture(k);
if (!tex)
continue;
compressTexture(tex, true);
}
}
}
} //compressPowerUpTextures
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ShaderBasedRenderer::setOverrideMaterial() void ShaderBasedRenderer::setOverrideMaterial()
{ {
@ -696,8 +671,6 @@ void ShaderBasedRenderer::onLoadWorld()
size_t height = viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y; size_t height = viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y;
RTT* rtts = new RTT(width, height); RTT* rtts = new RTT(width, height);
setRTT(rtts); setRTT(rtts);
compressPowerUpTextures();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -54,7 +54,6 @@ private:
std::vector<GlowData> m_glowing; std::vector<GlowData> m_glowing;
size_t m_nb_static_glowing; size_t m_nb_static_glowing;
void compressPowerUpTextures();
void setOverrideMaterial(); void setOverrideMaterial();
void addItemsInGlowingList(); void addItemsInGlowingList();

View File

@ -21,7 +21,7 @@
#include "graphics/show_curve.hpp" #include "graphics/show_curve.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
#include <IMeshSceneNode.h> #include <IMeshSceneNode.h>
@ -67,9 +67,9 @@ void ShowCurve::addEmptyMesh()
m_mesh = irr_driver->createQuadMesh(&m, m_mesh = irr_driver->createQuadMesh(&m,
/*create_one_quad*/ false); /*create_one_quad*/ false);
m_buffer = m_mesh->getMeshBuffer(0); m_buffer = m_mesh->getMeshBuffer(0);
m_buffer->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180))); m_buffer->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180)));
m_buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m_buffer->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
m_buffer->getMaterial().setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m_buffer->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
assert(m_buffer->getVertexType()==video::EVT_STANDARD); assert(m_buffer->getVertexType()==video::EVT_STANDARD);
} // addEmptyMesh } // addEmptyMesh

View File

@ -20,6 +20,7 @@
#include "graphics/skybox.hpp" #include "graphics/skybox.hpp"
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "graphics/texture_shader.hpp" #include "graphics/texture_shader.hpp"
#include <algorithm> #include <algorithm>
@ -160,22 +161,21 @@ void Skybox::generateCubeMapFromTextures()
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
{ {
unsigned idx = texture_permutation[i]; unsigned idx = texture_permutation[i];
video::IImage* img = static_cast<STKTexture*>
video::IImage* image = irr_driver->getVideoDriver() (m_skybox_textures[idx])->getTextureImage();
->createImageFromData(m_skybox_textures[idx]->getColorFormat(), assert(img != NULL);
m_skybox_textures[idx]->getSize(), img->copyToScaling(rgba[i], size, size);
m_skybox_textures[idx]->lock(), false );
m_skybox_textures[idx]->unlock();
image->copyToScaling(rgba[i], size, size);
image->drop();
#if defined(USE_GLES2) #if defined(USE_GLES2)
for (unsigned int j = 0; j < size * size; j++) if (CVS->isEXTTextureFormatBGRA8888Usable())
{ {
char tmp_val = rgba[i][j*4]; // BGRA image returned by getTextureImage causes black sky in gles
rgba[i][j*4] = rgba[i][j*4 + 2]; for (unsigned int j = 0; j < size * size; j++)
rgba[i][j*4 + 2] = tmp_val; {
char tmp_val = rgba[i][j * 4];
rgba[i][j * 4] = rgba[i][j * 4 + 2];
rgba[i][j * 4 + 2] = tmp_val;
}
} }
#endif #endif

View File

@ -23,7 +23,7 @@
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp" #include "karts/controller/controller.hpp"
@ -102,7 +102,7 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
video::SMaterial &mat = buffer->getMaterial(); video::SMaterial &mat = buffer->getMaterial();
// Meshes need a texture, otherwise stk crashes. // Meshes need a texture, otherwise stk crashes.
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
video::ITexture *red_texture = getUnicolorTexture(red); video::ITexture *red_texture = STKTexManager::getInstance()->getUnicolorTexture(red);
mat.setTexture(0, red_texture); mat.setTexture(0, red_texture);
#endif #endif

View File

@ -17,8 +17,12 @@
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
#include "graphics/irr_driver.hpp"
#include "graphics/spherical_harmonics.hpp" #include "graphics/spherical_harmonics.hpp"
#if defined(USE_GLES2)
#include "graphics/central_settings.hpp"
#endif
#include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include <algorithm> #include <algorithm>
@ -405,17 +409,22 @@ void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spher
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
{ {
unsigned idx = texture_permutation[i]; unsigned idx = texture_permutation[i];
video::IImage* img = static_cast<STKTexture*>
video::IImage* image = irr_driver->getVideoDriver()->createImageFromData( (m_spherical_harmonics_textures[idx])->getTextureImage();
m_spherical_harmonics_textures[idx]->getColorFormat(), assert(img != NULL);
m_spherical_harmonics_textures[idx]->getSize(), img->copyToScaling(sh_rgba[i], sh_w, sh_h);
m_spherical_harmonics_textures[idx]->lock(), #if defined(USE_GLES2)
false if (!CVS->isEXTTextureFormatBGRA8888Usable())
); {
m_spherical_harmonics_textures[idx]->unlock(); // Code here assume color format is BGRA
for (unsigned int j = 0; j < sh_w * sh_h; j++)
image->copyToScaling(sh_rgba[i], sh_w, sh_h); {
delete image; char tmp_val = sh_rgba[i][j * 4];
sh_rgba[i][j * 4] = sh_rgba[i][j * 4 + 2];
sh_rgba[i][j * 4 + 2] = tmp_val;
}
}
#endif
} //for (unsigned i = 0; i < 6; i++) } //for (unsigned i = 0; i < 6; i++)
Color *float_tex_cube[6]; Color *float_tex_cube[6];
@ -426,7 +435,7 @@ void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spher
{ {
delete[] sh_rgba[i]; delete[] sh_rgba[i];
delete[] float_tex_cube[i]; delete[] float_tex_cube[i];
} }
} //setSphericalHarmonicsTextures } //setSphericalHarmonicsTextures
/** Compute spherical harmonics coefficients from ambient light */ /** Compute spherical harmonics coefficients from ambient light */

View File

@ -18,10 +18,10 @@
#include "graphics/stars.hpp" #include "graphics/stars.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "utils/constants.hpp" #include "utils/constants.hpp"
@ -40,7 +40,10 @@ Stars::Stars(AbstractKart *kart)
m_parent_kart_node = kart->getNode(); m_parent_kart_node = kart->getNode();
m_enabled = false; m_enabled = false;
video::ITexture* texture = irr_driver->getTexture("starparticle.png"); video::ITexture* texture = STKTexManager::getInstance()->getTexture
("starparticle.png", true/*srgb*/, true/*premul_alpha*/,
false/*set_material*/, true/*mesh_tex*/);
Material* star_material = Material* star_material =
material_manager->getMaterial("starparticle.png"); material_manager->getMaterial("starparticle.png");

View File

@ -23,7 +23,6 @@
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/shared_gpu_objects.hpp" #include "graphics/shared_gpu_objects.hpp"
#include "graphics/texture_manager.hpp"
#include "graphics/texture_shader.hpp" #include "graphics/texture_shader.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
@ -110,10 +109,8 @@ void STKBillboard::render()
else else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
compressTexture(tex, true, true);
GLuint texid = getTextureGLuint(tex);
BillboardShader::getInstance()->use(); BillboardShader::getInstance()->use();
BillboardShader::getInstance()->setTextureUnits(texid); BillboardShader::getInstance()->setTextureUnits(tex->getOpenGLTextureName());
BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(),
irr_driver->getProjMatrix(), irr_driver->getProjMatrix(),
pos, Size); pos, Size);

View File

@ -23,9 +23,8 @@
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/materials.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
#include <IMaterialRenderer.h> #include <IMaterialRenderer.h>
@ -389,22 +388,14 @@ static void setTexture(GLMesh &mesh, unsigned i, bool is_srgb,
mat_name.c_str()); mat_name.c_str());
// use unicolor texture to replace missing texture // use unicolor texture to replace missing texture
mesh.textures[i] = mesh.textures[i] =
getUnicolorTexture(video::SColor(255, 127, 127, 127)); STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 127, 127, 127));
} }
compressTexture(mesh.textures[i], is_srgb);
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
{ {
if (!mesh.TextureHandles[i]) if (!mesh.TextureHandles[i])
{ {
mesh.TextureHandles[i] = glGetTextureSamplerHandleARB( mesh.TextureHandles[i] = mesh.textures[i]->getHandle();
getTextureGLuint(mesh.textures[i]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
insertTextureHandle(mesh.TextureHandles[i]);
} }
} }
#endif #endif
@ -479,22 +470,14 @@ void initTexturesTransparent(GLMesh &mesh)
{ {
if (!mesh.textures[0]) if (!mesh.textures[0])
{ {
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); mesh.textures[0] = STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 255, 255));
} }
compressTexture(mesh.textures[0], true);
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
{ {
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
{ {
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB( mesh.TextureHandles[0] = mesh.textures[0]->getHandle();
getTextureGLuint(mesh.textures[0]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
} }
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2017 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_STK_MESH_LOADER_HPP
#define HEADER_STK_MESH_LOADER_HPP
#include "../lib/irrlicht/source/Irrlicht/CSkinnedMesh.h"
#include <IMeshLoader.h>
#include <ISceneManager.h>
#include <IReadFile.h>
using namespace irr;
class STKMeshLoader : public scene::IMeshLoader
{
public:
//! Constructor
STKMeshLoader(scene::ISceneManager* smgr);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
virtual scene::IAnimatedMesh* createMesh(io::IReadFile* file);
private:
struct SB3dChunkHeader
{
c8 name[4];
s32 size;
};
struct SB3dChunk
{
SB3dChunk(const SB3dChunkHeader& header, long sp)
: length(header.size+8), startposition(sp)
{
name[0]=header.name[0];
name[1]=header.name[1];
name[2]=header.name[2];
name[3]=header.name[3];
}
c8 name[4];
s32 length;
long startposition;
};
struct SB3dTexture
{
core::stringc TextureName;
s32 Flags;
s32 Blend;
f32 Xpos;
f32 Ypos;
f32 Xscale;
f32 Yscale;
f32 Angle;
};
struct SB3dMaterial
{
SB3dMaterial() : red(1.0f), green(1.0f),
blue(1.0f), alpha(1.0f), shininess(0.0f), blend(1),
fx(0)
{
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
Textures[i]=0;
}
video::SMaterial Material;
f32 red, green, blue, alpha;
f32 shininess;
s32 blend,fx;
SB3dTexture *Textures[video::MATERIAL_MAX_TEXTURES];
};
bool load();
bool readChunkNODE(scene::CSkinnedMesh::SJoint* InJoint);
bool readChunkMESH(scene::CSkinnedMesh::SJoint* InJoint);
bool readChunkVRTS(scene::CSkinnedMesh::SJoint* InJoint);
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(scene::CSkinnedMesh::SJoint* InJoint);
bool readChunkKEYS(scene::CSkinnedMesh::SJoint* InJoint);
bool readChunkANIM();
bool readChunkTEXS();
bool readChunkBRUS();
void loadTextures(SB3dMaterial& material) const;
void readString(core::stringc& newstring);
void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<s32> AnimatedVertices_VertexID;
core::array<s32> AnimatedVertices_BufferID;
core::array<video::S3DVertex2TCoords> BaseVertices;
scene::ISceneManager* SceneManager;
scene::CSkinnedMesh* AnimatedMesh;
io::IReadFile* B3DFile;
//B3Ds have Vertex ID's local within the mesh I don't want this
// Variable needs to be class member due to recursion in calls
u32 VerticesStart;
bool NormalsInFile;
bool HasVertexColors;
bool ShowWarning;
};
#endif

View File

@ -26,7 +26,6 @@
#include "graphics/render_info.hpp" #include "graphics/render_info.hpp"
#include "graphics/rtts.hpp" #include "graphics/rtts.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/texture_manager.hpp"
#include "graphics/vao_manager.hpp" #include "graphics/vao_manager.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
@ -355,27 +354,18 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
{ {
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
{ {
mesh.TextureHandles[0] = mesh.TextureHandles[0] = mesh.textures[0]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
ObjectPass1Shader
::getInstance()->m_sampler_ids[0]);
}
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
} }
ObjectPass1Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]); ObjectPass1Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]);
} }
else else
#endif #endif
ObjectPass1Shader::getInstance()->setTextureUnits(getTextureGLuint(mesh.textures[0])); ObjectPass1Shader::getInstance()->setTextureUnits(mesh.textures[0]->getOpenGLTextureName());
ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel);
assert(mesh.vao); assert(mesh.vao);
glBindVertexArray(mesh.vao); glBindVertexArray(mesh.vao);
@ -421,34 +411,13 @@ void STKMeshSceneNode::render()
ObjectPass2Shader::getInstance()->m_sampler_ids[2]); ObjectPass2Shader::getInstance()->m_sampler_ids[2]);
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = mesh.TextureHandles[0] = mesh.textures[0]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
if (!mesh.TextureHandles[1]) if (!mesh.TextureHandles[1])
mesh.TextureHandles[1] = mesh.TextureHandles[1] = mesh.textures[1]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[1]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[1]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[1]);
insertTextureHandle(mesh.TextureHandles[1]);
}
if (!mesh.TextureHandles[2]) if (!mesh.TextureHandles[2])
mesh.TextureHandles[2] = mesh.TextureHandles[2] = mesh.textures[2]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[2]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[2]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[2]);
insertTextureHandle(mesh.TextureHandles[2]);
}
ObjectPass2Shader::getInstance() ObjectPass2Shader::getInstance()
->setTextureHandles(DiffuseHandle, SpecularHandle, SSAOHandle, ->setTextureHandles(DiffuseHandle, SpecularHandle, SSAOHandle,
@ -461,9 +430,9 @@ void STKMeshSceneNode::render()
irr_driver->getRenderTargetTexture(RTT_DIFFUSE), irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
irr_driver->getRenderTargetTexture(RTT_SPECULAR), irr_driver->getRenderTargetTexture(RTT_SPECULAR),
irr_driver->getRenderTargetTexture(RTT_HALF1_R), irr_driver->getRenderTargetTexture(RTT_HALF1_R),
getTextureGLuint(mesh.textures[0]), mesh.textures[0]->getOpenGLTextureName(),
getTextureGLuint(mesh.textures[1]), mesh.textures[1]->getOpenGLTextureName(),
getTextureGLuint(mesh.textures[2])); mesh.textures[2]->getOpenGLTextureName());
ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation,
mesh.texture_trans, mesh.texture_trans,
core::vector2df(0.0f, 0.0f)); core::vector2df(0.0f, 0.0f));
@ -529,19 +498,11 @@ void STKMeshSceneNode::render()
tmpcol.getGreen() / 255.0f, tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f); tmpcol.getBlue() / 255.0f);
compressTexture(mesh.textures[0], true);
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
{ {
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = mesh.TextureHandles[0] = mesh.textures[0]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
Shaders::TransparentFogShader::getInstance() Shaders::TransparentFogShader::getInstance()
->setTextureHandles(mesh.TextureHandles[0]); ->setTextureHandles(mesh.TextureHandles[0]);
} }
@ -549,7 +510,7 @@ void STKMeshSceneNode::render()
#endif #endif
{ {
Shaders::TransparentFogShader::getInstance() Shaders::TransparentFogShader::getInstance()
->setTextureUnits(getTextureGLuint(mesh.textures[0])); ->setTextureUnits(mesh.textures[0]->getOpenGLTextureName());
} }
Shaders::TransparentFogShader::getInstance() Shaders::TransparentFogShader::getInstance()
->setUniforms(AbsoluteTransformation, mesh.texture_trans, ->setUniforms(AbsoluteTransformation, mesh.texture_trans,
@ -572,24 +533,16 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (CVS->isAZDOEnabled()) if (CVS->isAZDOEnabled())
{ {
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = mesh.TextureHandles[0] = mesh.textures[0]->getHandle();
glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]),
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
{
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
insertTextureHandle(mesh.TextureHandles[0]);
}
Shaders::TransparentShader::getInstance()->setTextureHandles(mesh.TextureHandles[0]); Shaders::TransparentShader::getInstance()->setTextureHandles(mesh.TextureHandles[0]);
} }
else else
#endif #endif
Shaders::TransparentShader::getInstance()->setTextureUnits(getTextureGLuint(mesh.textures[0])); Shaders::TransparentShader::getInstance()->setTextureUnits(mesh.textures[0]->getOpenGLTextureName());
Shaders::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.texture_trans, 1.0f); Shaders::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.texture_trans, 1.0f);
assert(mesh.vao); assert(mesh.vao);

View File

@ -0,0 +1,241 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2017 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/stk_tex_manager.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/materials.hpp"
#include "graphics/stk_texture.hpp"
#include "io/file_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/log.hpp"
// ----------------------------------------------------------------------------
STKTexManager::~STKTexManager()
{
removeTexture(NULL/*texture*/, true/*remove_all*/);
} // ~STKTexManager
// ----------------------------------------------------------------------------
STKTexture* STKTexManager::findTextureInFileSystem(const std::string& filename,
std::string* full_path)
{
io::path relative_path = file_manager->searchTexture(filename).c_str();
if (relative_path.empty())
{
Log::warn("STKTexManager", "Failed to load %s.", filename.c_str());
return NULL;
}
*full_path =
file_manager->getFileSystem()->getAbsolutePath(relative_path).c_str();
for (auto p : m_all_textures)
{
if (p.second == NULL)
continue;
if (*full_path == p.first)
return p.second;
}
return NULL;
} // findTextureInFileSystem
// ----------------------------------------------------------------------------
video::ITexture* STKTexManager::getTexture(const std::string& path, bool srgb,
bool premul_alpha,
bool set_material, bool mesh_tex,
bool no_upload, bool single_channel)
{
auto ret = m_all_textures.find(path);
if (!no_upload && ret != m_all_textures.end())
return ret->second;
STKTexture* new_texture = NULL;
std::string full_path;
if (path.find('/') == std::string::npos)
{
new_texture = findTextureInFileSystem(path, &full_path);
if (full_path.empty())
return NULL;
if (!no_upload && new_texture)
return new_texture;
}
new_texture = new STKTexture(full_path.empty() ? path : full_path, srgb,
premul_alpha, set_material, mesh_tex, no_upload, single_channel);
if (new_texture->getOpenGLTextureName() == 0 && !no_upload)
{
m_all_textures[new_texture->getName().getPtr()] = NULL;
delete new_texture;
return NULL;
}
if (!no_upload)
addTexture(new_texture);
return new_texture;
} // getTexture
// ----------------------------------------------------------------------------
void STKTexManager::addTexture(STKTexture* texture)
{
m_all_textures[texture->getName().getPtr()] = texture;
} // addTexture
// ----------------------------------------------------------------------------
void STKTexManager::removeTexture(STKTexture* texture, bool remove_all)
{
#ifdef DEBUG
std::vector<std::string> undeleted_texture;
#endif
auto p = m_all_textures.begin();
while (p != m_all_textures.end())
{
if (remove_all || p->second == texture)
{
if (remove_all && p->second == NULL)
{
p = m_all_textures.erase(p);
continue;
}
#ifdef DEBUG
if (remove_all && p->second->getReferenceCount() != 1)
undeleted_texture.push_back(p->second->getName().getPtr());
#endif
p->second->drop();
p = m_all_textures.erase(p);
}
else
{
p++;
}
}
#ifdef DEBUG
if (!remove_all) return;
for (const std::string& s : undeleted_texture)
{
Log::error("STKTexManager", "%s undeleted!", s.c_str());
}
#endif
} // removeTexture
// ----------------------------------------------------------------------------
void STKTexManager::dumpAllTexture(bool mesh_texture)
{
for (auto p : m_all_textures)
{
if (!p.second || (mesh_texture && !p.second->isMeshTexture()))
continue;
Log::info("STKTexManager", "%s size: %0.2fK", p.first.c_str(),
float(p.second->getTextureSize()) / 1024);
}
} // dumpAllTexture
// ----------------------------------------------------------------------------
int STKTexManager::dumpTextureUsage()
{
int size = 0;
for (auto p : m_all_textures)
{
if (p.second == NULL)
continue;
size += p.second->getTextureSize() / 1024 / 1024;
}
Log::info("STKTexManager", "Total %dMB", size);
return size;
} // dumpAllTexture
// ----------------------------------------------------------------------------
video::ITexture* STKTexManager::getUnicolorTexture(const irr::video::SColor &c)
{
std::string name = StringUtils::toString(c.color) + "unic";
auto ret = m_all_textures.find(name);
if (ret != m_all_textures.end())
return ret->second;
uint8_t* data = new uint8_t[2 * 2 * 4];
memcpy(data, &c.color, sizeof(video::SColor));
memcpy(data + 4, &c.color, sizeof(video::SColor));
memcpy(data + 8, &c.color, sizeof(video::SColor));
memcpy(data + 12, &c.color, sizeof(video::SColor));
STKTexture* texture = new STKTexture(data, name, 2);
addTexture(texture);
return texture;
} // getUnicolorTexture
// ----------------------------------------------------------------------------
core::stringw STKTexManager::reloadTexture(const irr::core::stringw& name)
{
core::stringw result;
#ifndef SERVER_ONLY
if (CVS->isTextureCompressionEnabled())
return L"Please disable texture compression for reloading textures.";
if (name.empty())
{
for (auto p : m_all_textures)
{
if (p.second == NULL || !p.second->isMeshTexture())
continue;
p.second->reload();
Log::info("STKTexManager", "%s reloaded",
p.second->getName().getPtr());
}
return L"All textures reloaded.";
}
core::stringw list = name;
list.make_lower().replace(L'\u005C', L'\u002F');
std::vector<std::string> names =
StringUtils::split(StringUtils::wideToUtf8(list), ';');
for (const std::string& fname : names)
{
for (auto p : m_all_textures)
{
if (p.second == NULL || !p.second->isMeshTexture())
continue;
std::string tex_path =
StringUtils::toLowerCase(p.second->getName().getPtr());
std::string tex_name = StringUtils::getBasename(tex_path);
if (fname == tex_name || fname == tex_path)
{
p.second->reload();
result += tex_name.c_str();
result += L" ";
break;
}
}
}
if (result.empty())
return L"Texture(s) not found!";
#endif // !SERVER_ONLY
return result + "reloaded.";
} // reloadTexture
// ----------------------------------------------------------------------------
void STKTexManager::reset()
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
if (!CVS->isAZDOEnabled()) return;
for (auto p : m_all_textures)
{
if (p.second == NULL)
continue;
p.second->unloadHandle();
}
// Driver seems to crash if texture handles are not cleared...
ObjectPass1Shader::getInstance()->recreateTrilinearSampler(0);
#endif
} // reset

View File

@ -0,0 +1,75 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2017 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_STK_TEX_MANAGER_HPP
#define HEADER_STK_TEX_MANAGER_HPP
#include "graphics/gl_headers.hpp"
#include "utils/no_copy.hpp"
#include "utils/singleton.hpp"
#include "irrString.h"
#include <algorithm>
#include <string>
#include <unordered_map>
class STKTexture;
namespace irr
{
namespace video { class ITexture; class SColor; }
}
class STKTexManager : public Singleton<STKTexManager>, NoCopy
{
private:
std::unordered_map<std::string, STKTexture*> m_all_textures;
// ------------------------------------------------------------------------
STKTexture* findTextureInFileSystem(const std::string& filename,
std::string* full_path);
public:
// ------------------------------------------------------------------------
STKTexManager() {}
// ------------------------------------------------------------------------
~STKTexManager();
// ------------------------------------------------------------------------
irr::video::ITexture* getTexture(const std::string& path,
bool srgb = false,
bool premul_alpha = false,
bool set_material = false,
bool mesh_tex = false,
bool no_upload = false,
bool single_channel = false);
// ------------------------------------------------------------------------
irr::video::ITexture* getUnicolorTexture(const irr::video::SColor &c);
// ------------------------------------------------------------------------
void addTexture(STKTexture* texture);
// ------------------------------------------------------------------------
void removeTexture(STKTexture* texture, bool remove_all = false);
// ------------------------------------------------------------------------
void dumpAllTexture(bool mesh_texture);
// ------------------------------------------------------------------------
int dumpTextureUsage();
// ------------------------------------------------------------------------
irr::core::stringw reloadTexture(const irr::core::stringw& name);
// ------------------------------------------------------------------------
void reset();
}; // STKTexManager
#endif

View File

@ -22,7 +22,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_billboard.hpp" #include "graphics/stk_billboard.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include <SMesh.h> #include <SMesh.h>
#include <SMeshBuffer.h> #include <SMeshBuffer.h>
#include <ISceneManager.h> #include <ISceneManager.h>
@ -123,8 +123,8 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, FontWithFace* fo
{ {
buffer = new scene::SMeshBuffer(); buffer = new scene::SMeshBuffer();
buffer->getMaterial().setTexture(0, m_chars[i].m_texture); buffer->getMaterial().setTexture(0, m_chars[i].m_texture);
buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); buffer->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
buffer->getMaterial().setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); buffer->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
buffer->getMaterial().MaterialType = Shaders::getShader(ES_OBJECT_UNLIT); buffer->getMaterial().MaterialType = Shaders::getShader(ES_OBJECT_UNLIT);
buffers[m_chars[i].m_texture] = buffer; buffers[m_chars[i].m_texture] = buffer;
} }

View File

@ -0,0 +1,548 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2017 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/stk_texture.hpp"
#include "config/user_config.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/materials.hpp"
#include "modes/profile_world.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include <fstream>
#include <functional>
#if !defined(USE_GLES2)
static const uint8_t CACHE_VERSION = 1;
#endif
// ----------------------------------------------------------------------------
STKTexture::STKTexture(const std::string& path, bool srgb, bool premul_alpha,
bool set_material, bool mesh_tex, bool no_upload,
bool single_channel)
: video::ITexture(path.c_str()), m_texture_handle(0), m_srgb(srgb),
m_premul_alpha(premul_alpha), m_mesh_texture(mesh_tex),
m_single_channel(single_channel), m_material(NULL),
m_texture_name(0), m_texture_size(0), m_texture_image(NULL)
{
if (set_material)
{
m_material = material_manager->getMaterialFor(this);
m_mesh_texture = true;
}
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
m_srgb = false;
if (!CVS->isARBTextureSwizzleUsable())
m_single_channel = false;
#endif
reload(no_upload);
} // STKTexture
// ----------------------------------------------------------------------------
STKTexture::STKTexture(uint8_t* data, const std::string& name, size_t size,
bool single_channel)
: video::ITexture(name.c_str()), m_texture_handle(0), m_srgb(false),
m_premul_alpha(false), m_mesh_texture(false),
m_single_channel(single_channel), m_material(NULL),
m_texture_name(0), m_texture_size(0), m_texture_image(NULL)
{
m_size.Width = size;
m_size.Height = size;
m_orig_size = m_size;
reload(false/*no_upload*/, data);
} // STKTexture
// ----------------------------------------------------------------------------
STKTexture::STKTexture(video::IImage* img, const std::string& name)
: video::ITexture(name.c_str()), m_texture_handle(0), m_srgb(false),
m_premul_alpha(false), m_mesh_texture(false),
m_single_channel(false), m_material(NULL), m_texture_name(0),
m_texture_size(0), m_texture_image(NULL)
{
reload(false/*no_upload*/, NULL/*preload_data*/, img);
} // STKTexture
// ----------------------------------------------------------------------------
STKTexture::~STKTexture()
{
#ifndef SERVER_ONLY
unloadHandle();
if (m_texture_name != 0)
{
glDeleteTextures(1, &m_texture_name);
}
#endif // !SERVER_ONLY
if (m_texture_image != NULL)
m_texture_image->drop();
} // ~STKTexture
// ----------------------------------------------------------------------------
void STKTexture::reload(bool no_upload, uint8_t* preload_data,
video::IImage* preload_img)
{
if (ProfileWorld::isNoGraphics())
{
m_texture_name = 1;
if (preload_data)
delete[] preload_data;
if (preload_img)
preload_img->drop();
return;
}
#ifndef SERVER_ONLY
irr_driver->getDevice()->getLogger()->setLogLevel(ELL_NONE);
std::string compressed_texture;
#if !defined(USE_GLES2)
if (!no_upload && m_mesh_texture && CVS->isTextureCompressionEnabled())
{
std::string orig_file = NamedPath.getPtr();
std::string basename = StringUtils::getBasename(orig_file);
std::string container_id;
if (file_manager->searchTextureContainerId(container_id, basename))
{
std::string cache_subdir = "hd/";
if ((UserConfigParams::m_high_definition_textures & 0x01) == 0x01)
{
cache_subdir = "hd/";
}
else
{
cache_subdir = StringUtils::insertValues("resized_%i/",
(int)UserConfigParams::m_max_texture_size);
}
std::string cache_dir = file_manager->getCachedTexturesDir() +
cache_subdir + container_id;
compressed_texture = cache_dir + "/" + basename + ".stktz";
if (loadCompressedTexture(compressed_texture))
{
Log::debug("STKTexture", "Compressed %s for texture %s",
compressed_texture.c_str(), orig_file.c_str());
return;
}
file_manager->checkAndCreateDirectoryP(cache_dir);
}
else
{
Log::warn("STKTexture", "Cannot find container_id for texture %s",
orig_file.c_str());
}
}
#endif
video::IImage* orig_img = NULL;
uint8_t* data = preload_data;
if (data == NULL)
{
orig_img = preload_img ? preload_img :
irr_driver->getVideoDriver()->createImageFromFile(NamedPath);
if (orig_img == NULL)
{
Log::warn("STKTexture", "No image %s.", NamedPath.getPtr());
return;
}
if (orig_img->getDimension().Width == 0 ||
orig_img->getDimension().Height == 0)
{
Log::warn("STKTexture", "image %s has 0 size.",
NamedPath.getPtr());
orig_img->drop();
return;
}
orig_img = resizeImage(orig_img, &m_orig_size, &m_size);
applyMask(orig_img);
data = (uint8_t*)orig_img->lock();
if (m_single_channel)
{
uint8_t* sc = new uint8_t[m_size.Width * m_size.Height];
for (unsigned int i = 0; i < m_size.Width * m_size.Height; i++)
sc[i] = data[4 * i + 3];
orig_img->unlock();
orig_img->drop();
orig_img = NULL;
data = sc;
}
}
const unsigned int w = m_size.Width;
const unsigned int h = m_size.Height;
unsigned int format = m_single_channel ? GL_RED : GL_BGRA;
unsigned int internal_format = m_single_channel ? GL_R8 : GL_RGBA;
#if !defined(USE_GLES2)
if (m_mesh_texture && CVS->isTextureCompressionEnabled())
{
internal_format = m_single_channel ? GL_COMPRESSED_RED_RGTC1 :
m_srgb ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
else
{
internal_format =
m_single_channel ? GL_R8 : m_srgb ? GL_SRGB_ALPHA : GL_RGBA;
}
#endif
#if defined(USE_GLES2)
if (!CVS->isEXTTextureFormatBGRA8888Usable() && !m_single_channel)
{
format = GL_RGBA;
for (unsigned int i = 0; i < w * h; i++)
{
uint8_t tmp_val = data[i * 4];
data[i * 4] = data[i * 4 + 2];
data[i * 4 + 2] = tmp_val;
}
}
#endif
if (m_premul_alpha && !m_single_channel)
{
for (unsigned int i = 0; i < w * h; i++)
{
float alpha = data[4 * i + 3];
if (alpha > 0.0f)
alpha = pow(alpha / 255.f, 1.f / 2.2f);
data[i * 4] = (uint8_t)(data[i * 4] * alpha);
data[i * 4 + 1] = (uint8_t)(data[i * 4 + 1] * alpha);
data[i * 4 + 2] = (uint8_t)(data[i * 4 + 2] * alpha);
}
}
if (!no_upload)
{
const bool reload = m_texture_name != 0;
if (!reload)
glGenTextures(1, &m_texture_name);
glBindTexture(GL_TEXTURE_2D, m_texture_name);
if (!reload)
{
if (m_single_channel)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
}
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, w, h, 0, format,
GL_UNSIGNED_BYTE, data);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format,
GL_UNSIGNED_BYTE, data);
}
if (orig_img)
orig_img->unlock();
if (hasMipMaps())
glGenerateMipmap(GL_TEXTURE_2D);
}
m_texture_size = w * h * (m_single_channel ? 1 : 4);
if (no_upload)
m_texture_image = orig_img;
else if (orig_img)
orig_img->drop();
else
delete[] data;
if (!compressed_texture.empty())
saveCompressedTexture(compressed_texture);
if (!no_upload)
glBindTexture(GL_TEXTURE_2D, 0);
irr_driver->getDevice()->getLogger()->setLogLevel(ELL_WARNING);
#endif // !SERVER_ONLY
} // reload
// ----------------------------------------------------------------------------
video::IImage* STKTexture::resizeImage(video::IImage* orig_img,
core::dimension2du* new_img_size,
core::dimension2du* new_tex_size)
{
video::IImage* image = orig_img;
#ifndef SERVER_ONLY
const core::dimension2du& old_size = image->getDimension();
core::dimension2du img_size = old_size;
const float ratio = float(img_size.Width) / float(img_size.Height);
const unsigned int drv_max_size =
irr_driver->getVideoDriver()->getMaxTextureSize().Width;
if ((img_size.Width > drv_max_size) && (ratio >= 1.0f))
{
img_size.Width = drv_max_size;
img_size.Height = (unsigned)(drv_max_size / ratio);
}
else if (img_size.Height > drv_max_size)
{
img_size.Height = drv_max_size;
img_size.Width = (unsigned)(drv_max_size * ratio);
}
if (img_size != old_size)
{
video::IImage* new_img = irr_driver->getVideoDriver()
->createImage(video::ECF_A8R8G8B8, img_size);
image->copyToScaling(new_img);
image->drop();
image = new_img;
}
core::dimension2du tex_size = img_size.getOptimalSize
(!irr_driver->getVideoDriver()->queryFeature(video::EVDF_TEXTURE_NPOT));
const core::dimension2du& max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
if (max_size.Width > 0 && tex_size.Width > max_size.Width)
tex_size.Width = max_size.Width;
if (max_size.Height > 0 && tex_size.Height > max_size.Height)
tex_size.Height = max_size.Height;
if (image->getColorFormat() != video::ECF_A8R8G8B8 ||
tex_size != img_size)
{
video::IImage* new_texture = irr_driver
->getVideoDriver()->createImage(video::ECF_A8R8G8B8, tex_size);
if (tex_size != img_size)
image->copyToScaling(new_texture);
else
image->copyTo(new_texture);
image->drop();
image = new_texture;
}
if (new_img_size && new_tex_size)
{
*new_img_size = img_size;
*new_tex_size = tex_size;
}
#endif // !SERVER_ONLY
return image;
} // resizeImage
// ----------------------------------------------------------------------------
void STKTexture::applyMask(video::IImage* orig_img)
{
#ifndef SERVER_ONLY
if (m_material && !m_material->getAlphaMask().empty())
{
video::IImage* converted_mask = irr_driver->getVideoDriver()
->createImageFromFile(m_material->getAlphaMask().c_str());
if (converted_mask == NULL)
{
Log::warn("STKTexture", "Applying mask failed for '%s'!",
m_material->getAlphaMask().c_str());
return;
}
converted_mask = resizeImage(converted_mask);
if (converted_mask->lock())
{
const core::dimension2du& dim = orig_img->getDimension();
for (unsigned int x = 0; x < dim.Width; x++)
{
for (unsigned int y = 0; y < dim.Height; y++)
{
video::SColor col = orig_img->getPixel(x, y);
video::SColor alpha = converted_mask->getPixel(x, y);
col.setAlpha(alpha.getRed());
orig_img->setPixel(x, y, col, false);
} // for y
} // for x
}
converted_mask->unlock();
converted_mask->drop();
}
#endif // !SERVER_ONLY
} // applyMask
//-----------------------------------------------------------------------------
/** Try to load a compressed texture from the given file name.
* Data in the specified file need to have a specific format. See the
* saveCompressedTexture() function for a description of the format.
* \return true if the loading succeeded, false otherwise.
* \see saveCompressedTexture
*/
bool STKTexture::loadCompressedTexture(const std::string& file_name)
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
std::ifstream ifs(file_name.c_str(), std::ios::in | std::ios::binary);
if (!ifs.is_open())
return false;
int internal_format;
uint8_t cache_verison;
ifs.read((char*)&cache_verison, sizeof(uint8_t));
if (cache_verison != CACHE_VERSION)
{
Log::warn("STKTexture", "%s version %d is not supported!",
file_name.c_str(), cache_verison);
ifs.close();
// Remove the file later if we have more version
return false;
}
ifs.read((char*)&internal_format, sizeof(int));
ifs.read((char*)&m_size.Width, sizeof(unsigned int));
ifs.read((char*)&m_size.Height, sizeof(unsigned int));
ifs.read((char*)&m_orig_size.Width, sizeof(unsigned int));
ifs.read((char*)&m_orig_size.Height, sizeof(unsigned int));
ifs.read((char*)&m_texture_size, sizeof(unsigned int));
if (ifs.fail() || m_texture_size == 0)
return false;
char *data = new char[m_texture_size];
ifs.read(data, m_texture_size);
if (!ifs.fail())
{
// No on the fly reload is supported for compressed texture
assert(m_texture_name == 0);
glGenTextures(1, &m_texture_name);
glBindTexture(GL_TEXTURE_2D, m_texture_name);
if (internal_format == GL_COMPRESSED_RED_RGTC1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
}
glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format,
m_size.Width, m_size.Height, 0, m_texture_size, (GLvoid*)data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
delete[] data;
ifs.close();
return true;
}
delete[] data;
#endif
return false;
} // loadCompressedTexture
//-----------------------------------------------------------------------------
/** Try to save the last texture sent to glTexImage2D in a file of the given
* file name. This function should only be used for textures sent to
* glTexImage2D with a compressed internal format as argument.<br>
* \note The following format is used to save the compressed texture:<br>
* <version><internal-format><w><h><orig_w><orig_h><size><data> <br>
* The first element is the version of cache, next six elements are
* integers and the last one is stored on \c size bytes.
* \see loadCompressedTexture
*/
void STKTexture::saveCompressedTexture(const std::string& compressed_tex)
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
int internal_format;
int compression_successful = 0;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT,
(GLint *)&internal_format);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
(GLint *)&m_size.Width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
(GLint *)&m_size.Height);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED,
(GLint *)&compression_successful);
if (compression_successful == 0) return;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&m_texture_size);
if (m_texture_size == 0) return;
char *data = new char[m_texture_size];
glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data);
std::ofstream ofs(compressed_tex.c_str(),
std::ios::out | std::ios::binary);
if (ofs.is_open())
{
ofs.write((char*)&CACHE_VERSION, sizeof(uint8_t));
ofs.write((char*)&internal_format, sizeof(int));
ofs.write((char*)&m_size.Width, sizeof(unsigned int));
ofs.write((char*)&m_size.Height, sizeof(unsigned int));
ofs.write((char*)&m_orig_size.Width, sizeof(unsigned int));
ofs.write((char*)&m_orig_size.Height, sizeof(unsigned int));
ofs.write((char*)&m_texture_size, sizeof(unsigned int));
ofs.write(data, m_texture_size);
ofs.close();
}
delete[] data;
#endif
} // saveCompressedTexture
//-----------------------------------------------------------------------------
bool STKTexture::hasMipMaps() const
{
#ifndef SERVER_ONLY
return CVS->getGLSLVersion() >= 130;
#endif // !SERVER_ONLY
return false;
} // hasMipMaps
//-----------------------------------------------------------------------------
void* STKTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level)
{
if (m_texture_image)
return m_texture_image->lock();
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
uint8_t* pixels = new uint8_t[m_size.Width * m_size.Height * 4]();
GLint tmp_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmp_texture);
glBindTexture(GL_TEXTURE_2D, m_texture_name);
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, tmp_texture);
return pixels;
#endif // !SERVER_ONLY
return NULL;
} // lock
//-----------------------------------------------------------------------------
u64 STKTexture::getHandle()
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
assert(CVS->isAZDOEnabled());
if (m_texture_handle != 0) return m_texture_handle;
m_texture_handle =
glGetTextureSamplerHandleARB( m_texture_name,
ObjectPass1Shader::getInstance()->m_sampler_ids[0]);
if (!glIsTextureHandleResidentARB(m_texture_handle))
glMakeTextureHandleResidentARB(m_texture_handle);
#endif
return m_texture_handle;
} // getHandle
//-----------------------------------------------------------------------------
void STKTexture::unloadHandle()
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
if (CVS->isAZDOEnabled())
{
if (m_texture_handle == 0) return;
glMakeTextureHandleNonResidentARB(m_texture_handle);
m_texture_handle = 0;
}
#endif
} // unloadHandle

View File

@ -0,0 +1,128 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2017 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_STK_TEXTURE_HPP
#define HEADER_STK_TEXTURE_HPP
#include "graphics/gl_headers.hpp"
#include "utils/no_copy.hpp"
#include <string>
#include <ITexture.h>
using namespace irr;
class Material;
class STKTexture : public video::ITexture, NoCopy
{
private:
core::dimension2d<u32> m_size, m_orig_size;
uint64_t m_texture_handle;
bool m_srgb, m_premul_alpha, m_mesh_texture, m_single_channel;
Material* m_material;
GLuint m_texture_name;
unsigned int m_texture_size;
video::IImage* m_texture_image;
// ------------------------------------------------------------------------
video::IImage* resizeImage(video::IImage* orig_img,
core::dimension2du* new_img_size = NULL,
core::dimension2du* new_tex_size = NULL);
// ------------------------------------------------------------------------
void applyMask(video::IImage* orig_img);
// ------------------------------------------------------------------------
bool loadCompressedTexture(const std::string& file_name);
// ------------------------------------------------------------------------
void saveCompressedTexture(const std::string& file_name);
public:
// ------------------------------------------------------------------------
STKTexture(const std::string& path, bool srgb = false,
bool premul_alpha = false, bool set_material = false,
bool mesh_tex = false, bool no_upload = false,
bool single_channel = false);
// ------------------------------------------------------------------------
STKTexture(uint8_t* data, const std::string& name, size_t size,
bool single_channel = false);
// ------------------------------------------------------------------------
STKTexture(video::IImage* img, const std::string& name);
// ------------------------------------------------------------------------
virtual ~STKTexture();
// ------------------------------------------------------------------------
virtual void* lock(video::E_TEXTURE_LOCK_MODE mode =
video::ETLM_READ_WRITE, u32 mipmap_level = 0);
// ------------------------------------------------------------------------
virtual void unlock()
{
if (m_texture_image)
m_texture_image->unlock();
}
// ------------------------------------------------------------------------
virtual const core::dimension2d<u32>& getOriginalSize() const
{ return m_orig_size; }
// ------------------------------------------------------------------------
virtual const core::dimension2d<u32>& getSize() const { return m_size; }
// ------------------------------------------------------------------------
virtual video::E_DRIVER_TYPE getDriverType() const
{
#if defined(USE_GLES2)
return video::EDT_OGLES2;
#else
return video::EDT_OPENGL;
#endif
}
// ------------------------------------------------------------------------
virtual video::ECOLOR_FORMAT getColorFormat() const
{ return video::ECF_A8R8G8B8; }
// ------------------------------------------------------------------------
virtual u32 getPitch() const { return 0; }
// ------------------------------------------------------------------------
virtual bool hasMipMaps() const;
// ------------------------------------------------------------------------
virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {}
// ------------------------------------------------------------------------
virtual u32 getOpenGLTextureName() const { return m_texture_name; }
// ------------------------------------------------------------------------
virtual u64 getHandle();
// ------------------------------------------------------------------------
virtual void unloadHandle();
// ------------------------------------------------------------------------
bool isSrgb() const { return m_srgb; }
// ------------------------------------------------------------------------
bool isPremulAlpha() const { return m_premul_alpha; }
// ------------------------------------------------------------------------
bool isMeshTexture() const { return m_mesh_texture; }
// ------------------------------------------------------------------------
void setMeshTexture(bool val) { m_mesh_texture = val; }
// ------------------------------------------------------------------------
unsigned int getTextureSize() const { return m_texture_size; }
// ------------------------------------------------------------------------
void reload(bool no_upload = false, uint8_t* preload_data = NULL,
video::IImage* preload_img = NULL);
// ------------------------------------------------------------------------
video::IImage* getTextureImage() { return m_texture_image; }
}; // STKTexture
#endif

View File

@ -1,359 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef SERVER_ONLY
#include "graphics/texture_manager.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/materials.hpp"
#include "utils/string_utils.hpp"
#if defined(USE_GLES2)
#define _IRR_COMPILE_WITH_OGLES2_
#include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h"
#else
#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
#endif
#include <fstream>
#include <sstream>
GLuint getTextureGLuint(irr::video::ITexture *tex)
{
if (tex == NULL)
return 0;
#if defined(USE_GLES2)
return static_cast<irr::video::COGLES2Texture*>(tex)->getOpenGLTextureName();
#else
return static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
#endif
}
GLuint getDepthTexture(irr::video::ITexture *tex)
{
assert(tex->isRenderTarget());
#if defined(USE_GLES2)
return static_cast<irr::video::COGLES2FBOTexture*>(tex)->DepthBufferTexture;
#else
return static_cast<irr::video::COpenGLFBOTexture*>(tex)->DepthBufferTexture;
#endif
}
static std::set<irr::video::ITexture *> AlreadyTransformedTexture;
static std::map<int, video::ITexture*> unicolor_cache;
static std::vector<uint64_t> texture_handles;
void resetTextureTable()
{
#if !defined(USE_GLES2)
if (CVS->isAZDOEnabled())
{
// Driver seems to crash if texture handles are not cleared...
for (uint64_t& handle : texture_handles)
{
glMakeTextureHandleNonResidentARB(handle);
}
ObjectPass1Shader::getInstance()->recreateTrilinearSampler(0);
texture_handles.clear();
}
#endif
AlreadyTransformedTexture.clear();
}
void insertTextureHandle(uint64_t handle)
{
texture_handles.push_back(handle);
}
void cleanUnicolorTextures()
{
for (std::pair<const int, video::ITexture*>& uc : unicolor_cache)
{
uc.second->drop();
}
unicolor_cache.clear();
}
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
{
if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end())
return;
AlreadyTransformedTexture.insert(tex);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
std::string cached_file;
if (CVS->isTextureCompressionEnabled())
{
// Try to retrieve the compressed texture in cache
std::string tex_name = irr_driver->getTextureName(tex);
if (!tex_name.empty()) {
cached_file = file_manager->getTextureCacheLocation(tex_name) + ".gltz";
if (!file_manager->fileIsNewer(tex_name, cached_file)) {
if (loadCompressedTexture(cached_file))
return;
}
}
}
size_t w = tex->getSize().Width, h = tex->getSize().Height;
unsigned char *data = new unsigned char[w * h * 4];
memcpy(data, tex->lock(), w * h * 4);
tex->unlock();
unsigned internalFormat, Format;
Format = tex->hasAlpha() ? GL_BGRA : GL_BGR;
#if defined(USE_GLES2)
if (!CVS->isEXTTextureFormatBGRA8888Usable())
{
Format = tex->hasAlpha() ? GL_RGBA : GL_RGB;
for (unsigned int i = 0; i < w * h; i++)
{
char tmp_val = data[i*4];
data[i*4] = data[i*4 + 2];
data[i*4 + 2] = tmp_val;
}
}
#endif
if (premul_alpha)
{
for (unsigned i = 0; i < w * h; i++)
{
float alpha = data[4 * i + 3];
if (alpha > 0.)
alpha = pow(alpha / 255.f, 1.f / 2.2f);
data[4 * i] = (unsigned char)(data[4 * i] * alpha);
data[4 * i + 1] = (unsigned char)(data[4 * i + 1] * alpha);
data[4 * i + 2] = (unsigned char)(data[4 * i + 2] * alpha);
}
}
#if !defined(USE_GLES2)
if (!CVS->isTextureCompressionEnabled())
{
if (srgb)
internalFormat = (tex->hasAlpha()) ? GL_SRGB_ALPHA : GL_SRGB;
else
internalFormat = (tex->hasAlpha()) ? GL_RGBA : GL_RGB;
}
else
{
if (srgb)
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
else
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
}
#else
internalFormat = (tex->hasAlpha()) ? GL_RGBA : GL_RGB;
#endif
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, Format, GL_UNSIGNED_BYTE, (GLvoid *)data);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] data;
if (CVS->isTextureCompressionEnabled() && !cached_file.empty())
{
// Save the compressed texture in the cache for later use.
saveCompressedTexture(cached_file);
}
}
//-----------------------------------------------------------------------------
/** Try to load a compressed texture from the given file name.
* Data in the specified file need to have a specific format. See the
* saveCompressedTexture() function for a description of the format.
* \return true if the loading succeeded, false otherwise.
* \see saveCompressedTexture
*/
bool loadCompressedTexture(const std::string& compressed_tex)
{
std::ifstream ifs(compressed_tex.c_str(), std::ios::in | std::ios::binary);
if (!ifs.is_open())
return false;
int internal_format;
int w, h;
int size = -1;
ifs.read((char*)&internal_format, sizeof(int));
ifs.read((char*)&w, sizeof(int));
ifs.read((char*)&h, sizeof(int));
ifs.read((char*)&size, sizeof(int));
if (ifs.fail() || size == -1)
return false;
char *data = new char[size];
ifs.read(data, size);
if (!ifs.fail())
{
glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format,
w, h, 0, size, (GLvoid*)data);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] data;
ifs.close();
return true;
}
delete[] data;
return false;
}
//-----------------------------------------------------------------------------
/** Try to save the last texture sent to glTexImage2D in a file of the given
* file name. This function should only be used for textures sent to
* glTexImage2D with a compressed internal format as argument.<br>
* \note The following format is used to save the compressed texture:<br>
* <internal-format><width><height><size><data> <br>
* The first four elements are integers and the last one is stored
* on \c size bytes.
* \see loadCompressedTexture
*/
void saveCompressedTexture(const std::string& compressed_tex)
{
#if !defined(USE_GLES2)
int internal_format, width, height, size, compressionSuccessful;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internal_format);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint *)&width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint *)&height);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, (GLint *)&compressionSuccessful);
if (!compressionSuccessful)
return;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&size);
char *data = new char[size];
glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data);
std::ofstream ofs(compressed_tex.c_str(), std::ios::out | std::ios::binary);
if (ofs.is_open())
{
ofs.write((char*)&internal_format, sizeof(int));
ofs.write((char*)&width, sizeof(int));
ofs.write((char*)&height, sizeof(int));
ofs.write((char*)&size, sizeof(int));
ofs.write(data, size);
ofs.close();
}
delete[] data;
#endif
}
video::ITexture* getUnicolorTexture(const video::SColor &c)
{
std::map<int, video::ITexture*>::iterator it = unicolor_cache.find(c.color);
if (it != unicolor_cache.end())
{
return it->second;
}
else
{
unsigned tmp[4] = {
c.color,
c.color,
c.color,
c.color
};
video::IImage *img = irr_driver->getVideoDriver()->createImageFromData(video::ECF_A8R8G8B8, core::dimension2d<u32>(2, 2), tmp);
std::stringstream name;
name << "color" << c.color;
video::ITexture* tex = irr_driver->getVideoDriver()->addTexture(name.str().c_str(), img);
tex->grab();
// Only let our map hold the unicolor texture
irr_driver->getVideoDriver()->removeTexture(tex);
unicolor_cache[c.color] = tex;
img->drop();
return tex;
}
}
core::stringw reloadTexture(const core::stringw& name)
{
if (!CVS->isGLSL())
return L"Use shader based renderer to reload textures.";
if (CVS->isTextureCompressionEnabled())
return L"Please disable texture compression for reloading textures.";
if (name.empty())
{
for (video::ITexture* tex : AlreadyTransformedTexture)
reloadSingleTexture(tex);
return L"All textures reloaded.";
}
core::stringw result;
core::stringw list = name;
list.make_lower().replace(L'\u005C', L'\u002F');
std::vector<std::string> names =
StringUtils::split(StringUtils::wideToUtf8(list), ';');
for (const std::string& fname : names)
{
for (video::ITexture* tex : AlreadyTransformedTexture)
{
std::string tex_path =
StringUtils::toLowerCase(tex->getName().getPtr());
std::string tex_name = StringUtils::getBasename(tex_path);
if (fname == tex_name || fname == tex_path)
{
if (reloadSingleTexture(tex))
{
result += tex_name.c_str();
result += L" ";
break;
}
}
}
}
if (result.empty())
return L"Texture(s) not found!";
return result + "reloaded.";
}
bool reloadSingleTexture(video::ITexture* tex)
{
video::IImage* tmp =
irr_driver->getVideoDriver()->createImageFromFile(tex->getName());
if (tmp == NULL) return false;
const bool scaling = tmp->getDimension() != tex->getSize();
video::IImage* new_texture =
irr_driver->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
scaling ? tex->getSize() : tmp->getDimension());
if (scaling)
tmp->copyToScaling(new_texture);
else
tmp->copyTo(new_texture);
tmp->drop();
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, new_texture->getDimension().Width,
new_texture->getDimension().Height, GL_BGRA, GL_UNSIGNED_BYTE,
new_texture->lock());
new_texture->unlock();
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
#if defined(USE_GLES2)
static_cast<irr::video::COGLES2Texture*>(tex)->setImage(new_texture);
#else
static_cast<irr::video::COpenGLTexture*>(tex)->setImage(new_texture);
#endif
Log::info("TextureManager", "%s reloaded", tex->getName().getPtr());
return true;
}
#endif // !SERVER_ONLY

View File

@ -1,40 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_TEXTURE_MANAGER_HPP
#define HEADER_TEXTURE_MANAGER_HPP
#include "graphics/gl_headers.hpp"
#include <ITexture.h>
#include <SColor.h>
#include <string>
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void resetTextureTable();
void cleanUnicolorTextures();
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(const std::string& compressed_tex);
irr::video::ITexture* getUnicolorTexture(const irr::video::SColor &c);
void insertTextureHandle(uint64_t handle);
bool reloadSingleTexture(irr::video::ITexture *tex);
irr::core::stringw reloadTexture(const irr::core::stringw& name);
#endif

View File

@ -127,33 +127,5 @@ u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
return area.spriteno; return area.spriteno;
} // getSpriteNoFromChar } // getSpriteNoFromChar
// ------------------------------------------------------------------------
u32 ScalableFont::addLazyLoadCharacters(const wchar_t *c)
{
IGUISpriteBank* sp = m_face->getSpriteBank();
u32 tex_count = sp->getTextureCount();
if (!m_face->supportLazyLoadChar()) return tex_count;
m_face->insertCharacters(c);
m_face->updateCharactersList();
// Make sure text of billboard wasn't located in the last texture
for (const wchar_t p = *c; *c; c++)
{
const core::array<SGUISprite>& s = sp->getSprites();
const FontWithFace::FontArea& area =
m_face->getAreaFromCharacter(p, NULL/*fallback_font*/);
u32 cur_tex_no = s[area.spriteno].Frames[0].textureNumber;
if (cur_tex_no == (tex_count -1))
{
m_face->createNewGlyphPage();
return tex_count;
}
}
return tex_count -1;
} // addLazyLoadCharacters
} // end namespace gui } // end namespace gui
} // end namespace irr } // end namespace irr

View File

@ -86,8 +86,6 @@ public:
/** returns the sprite number from a given character */ /** returns the sprite number from a given character */
virtual u32 getSpriteNoFromChar(const wchar_t *c) const; virtual u32 getSpriteNoFromChar(const wchar_t *c) const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual u32 addLazyLoadCharacters(const wchar_t *s);
// ------------------------------------------------------------------------
// Below is not used: // Below is not used:
/** set an Pixel Offset on Drawing ( scale position on width ) */ /** set an Pixel Offset on Drawing ( scale position on width ) */
virtual void setKerningWidth (s32 kerning) {} virtual void setKerningWidth (s32 kerning) {}

View File

@ -57,6 +57,7 @@ IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false,
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
ModelViewWidget::~ModelViewWidget() ModelViewWidget::~ModelViewWidget()
{ {
clearModels();
GUIEngine::needsUpdate.remove(this); GUIEngine::needsUpdate.remove(this);
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
delete m_render_info; delete m_render_info;
@ -92,6 +93,7 @@ void ModelViewWidget::clearModels()
if (m_rtt_main_node != NULL) m_rtt_main_node->remove(); if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
if (m_light != NULL) m_light->remove(); if (m_light != NULL) m_light->remove();
if (m_camera != NULL) m_camera->remove(); if (m_camera != NULL) m_camera->remove();
irr_driver->clearLights();
m_rtt_main_node = NULL; m_rtt_main_node = NULL;
m_camera = NULL; m_camera = NULL;

View File

@ -309,11 +309,11 @@ void FileManager::init()
// Note that we can't push the texture search path in the constructor // Note that we can't push the texture search path in the constructor
// since this also adds a file archive to the file system - and // since this also adds a file archive to the file system - and
// m_file_system is deleted (in irr_driver) // m_file_system is deleted (in irr_driver)
pushTextureSearchPath(m_subdir_name[TEXTURE]); pushTextureSearchPath(m_subdir_name[TEXTURE], "textures");
if(fileExists(m_subdir_name[TEXTURE]+"deprecated/")) if (fileExists(m_subdir_name[TEXTURE]+"deprecated/"))
pushTextureSearchPath(m_subdir_name[TEXTURE]+"deprecated/"); pushTextureSearchPath(m_subdir_name[TEXTURE]+"deprecated/", "deprecatedtex");
pushTextureSearchPath(m_subdir_name[GUI]); pushTextureSearchPath(m_subdir_name[GUI], "gui");
pushModelSearchPath (m_subdir_name[MODEL]); pushModelSearchPath (m_subdir_name[MODEL]);
pushMusicSearchPath (m_subdir_name[MUSIC]); pushMusicSearchPath (m_subdir_name[MUSIC]);
@ -517,9 +517,9 @@ void FileManager::pushModelSearchPath(const std::string& path)
/** Adds a texture search path to the list of texture search paths. /** Adds a texture search path to the list of texture search paths.
* This path will be searched before any other existing paths. * This path will be searched before any other existing paths.
*/ */
void FileManager::pushTextureSearchPath(const std::string& path) void FileManager::pushTextureSearchPath(const std::string& path, const std::string& container_id)
{ {
m_texture_search_path.push_back(path); m_texture_search_path.push_back(TextureSearchPath(path, container_id));
const int n=m_file_system->getFileArchiveCount(); const int n=m_file_system->getFileArchiveCount();
m_file_system->addFileArchive(createAbsoluteFilename(path), m_file_system->addFileArchive(createAbsoluteFilename(path),
/*ignoreCase*/false, /*ignoreCase*/false,
@ -548,9 +548,9 @@ void FileManager::popTextureSearchPath()
{ {
if(!m_texture_search_path.empty()) if(!m_texture_search_path.empty())
{ {
std::string dir = m_texture_search_path.back(); TextureSearchPath dir = m_texture_search_path.back();
m_texture_search_path.pop_back(); m_texture_search_path.pop_back();
m_file_system->removeFileArchive(createAbsoluteFilename(dir)); m_file_system->removeFileArchive(createAbsoluteFilename(dir.m_texture_search_path));
} }
} // popTextureSearchPath } // popTextureSearchPath
@ -601,6 +601,29 @@ bool FileManager::findFile(std::string& full_path,
return false; return false;
} // findFile } // findFile
//-----------------------------------------------------------------------------
/** Tries to find the specified file in any of the given search paths.
* \param full_path On return contains the full path of the file, or
* "" if the file is not found.
* \param file_name The name of the file to look for.
* \param search_path The list of paths to search for the file.
* \return True if the file is found, false otherwise.
*/
bool FileManager::findFile(std::string& full_path,
const std::string& file_name,
const std::vector<TextureSearchPath>& search_path) const
{
for (std::vector<TextureSearchPath>::const_reverse_iterator
i = search_path.rbegin();
i != search_path.rend(); ++i)
{
full_path = i->m_texture_search_path + file_name;
if (m_file_system->existFile(full_path.c_str())) return true;
}
full_path = "";
return false;
} // findFile
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
std::string FileManager::getAssetChecked(FileManager::AssetType type, std::string FileManager::getAssetChecked(FileManager::AssetType type,
const std::string& name, const std::string& name,
@ -693,6 +716,27 @@ std::string FileManager::searchTexture(const std::string& file_name) const
return path; return path;
} // searchTexture } // searchTexture
//-----------------------------------------------------------------------------
bool FileManager::searchTextureContainerId(std::string& container_id,
const std::string& file_name) const
{
std::string full_path;
for (std::vector<TextureSearchPath>::const_reverse_iterator
i = m_texture_search_path.rbegin();
i != m_texture_search_path.rend(); ++i)
{
full_path = i->m_texture_search_path + file_name;
if (m_file_system->existFile(full_path.c_str()))
{
container_id = i->m_container_id;
return true;
}
}
full_path = "";
return false;
} // findFile
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Returns the list of all directories in which music files are searched. /** Returns the list of all directories in which music files are searched.
*/ */
@ -1137,35 +1181,6 @@ void FileManager::redirectOutput()
Log::openOutputFiles(logoutfile); Log::openOutputFiles(logoutfile);
} // redirectOutput } // redirectOutput
//-----------------------------------------------------------------------------
/** Returns the theoretical location of the cached version of a texture
* depending of the current config. (This function also works for directories:
* in this case the returned directory will be the cache location for all
* textures that you will find in the specified directory. The specified
* directory must end with '/')
* \note The returned location is where the cached data should be read or
* written but the file itseft does not necessarity exist. However, the
* directory structure is automatically created if it does not exist.
*/
std::string FileManager::getTextureCacheLocation(const std::string& filename)
{
std::string file = StringUtils::getBasename(filename);
std::string parent_dir = StringUtils::getPath(filename);
if (StringUtils::hasSuffix(parent_dir, "/"))
parent_dir = parent_dir.substr(0, parent_dir.size() - 1);
parent_dir = StringUtils::getBasename(parent_dir);
std::string cache_subdir = (UserConfigParams::m_high_definition_textures & 0x01) == 0x01
? "hd/"
: "resized/";
std::string cached_file =
getCachedTexturesDir() + cache_subdir + parent_dir + "/";
checkAndCreateDirectoryP(cached_file);
cached_file += file;
return cached_file;
} // getTextureCacheLocation
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Returns the directory for addon files. */ /** Returns the directory for addon files. */
const std::string &FileManager::getAddonsDir() const const std::string &FileManager::getAddonsDir() const

View File

@ -37,6 +37,17 @@ using namespace irr;
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
struct TextureSearchPath
{
std::string m_texture_search_path;
std::string m_container_id;
TextureSearchPath(std::string path, std::string container_id) :
m_texture_search_path(path), m_container_id(container_id)
{
}
};
/** /**
* \brief class handling files and paths * \brief class handling files and paths
* \ingroup io * \ingroup io
@ -52,6 +63,7 @@ public:
SCRIPT, SFX, SHADER, SKIN, TEXTURE, TTF, SCRIPT, SFX, SHADER, SKIN, TEXTURE, TTF,
TRANSLATION, ASSET_MAX = TRANSLATION, TRANSLATION, ASSET_MAX = TRANSLATION,
ASSET_COUNT}; ASSET_COUNT};
private: private:
/** The names of the various subdirectories of the asset types. */ /** The names of the various subdirectories of the asset types. */
@ -84,14 +96,19 @@ private:
/** Directory where user-defined grand prix are stored. */ /** Directory where user-defined grand prix are stored. */
std::string m_gp_dir; std::string m_gp_dir;
std::vector<TextureSearchPath> m_texture_search_path;
std::vector<std::string> std::vector<std::string>
m_texture_search_path,
m_model_search_path, m_model_search_path,
m_music_search_path; m_music_search_path;
bool findFile(std::string& full_path, bool findFile(std::string& full_path,
const std::string& fname, const std::string& fname,
const std::vector<std::string>& search_path) const std::vector<std::string>& search_path)
const; const;
bool findFile(std::string& full_path,
const std::string& fname,
const std::vector<TextureSearchPath>& search_path)
const;
void makePath(std::string& path, const std::string& dir, void makePath(std::string& path, const std::string& dir,
const std::string& fname) const; const std::string& fname) const;
bool checkAndCreateDirectory(const std::string &path); bool checkAndCreateDirectory(const std::string &path);
@ -124,7 +141,6 @@ public:
std::string getReplayDir() const; std::string getReplayDir() const;
std::string getCachedTexturesDir() const; std::string getCachedTexturesDir() const;
std::string getGPDir() const; std::string getGPDir() const;
std::string getTextureCacheLocation(const std::string& filename);
bool checkAndCreateDirectoryP(const std::string &path); bool checkAndCreateDirectoryP(const std::string &path);
const std::string &getAddonsDir() const; const std::string &getAddonsDir() const;
std::string getAddonsFile(const std::string &name); std::string getAddonsFile(const std::string &name);
@ -157,6 +173,9 @@ public:
return fileExists(std::string(prefix) + path); return fileExists(std::string(prefix) + path);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool searchTextureContainerId(std::string& container_id,
const std::string& file_name) const;
// ------------------------------------------------------------------------
/** Returns the name of the stdout file for log messages. */ /** Returns the name of the stdout file for log messages. */
static const std::string& getStdoutName() { return m_stdout_filename; } static const std::string& getStdoutName() { return m_stdout_filename; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -165,7 +184,7 @@ public:
bool make_full_path=false) const; bool make_full_path=false) const;
void pushTextureSearchPath(const std::string& path); void pushTextureSearchPath(const std::string& path, const std::string& container_id);
void pushModelSearchPath(const std::string& path); void pushModelSearchPath(const std::string& path);
void popTextureSearchPath(); void popTextureSearchPath();
void popModelSearchPath(); void popModelSearchPath();

View File

@ -23,7 +23,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "items/plunger.hpp" #include "items/plunger.hpp"
#include "items/projectile_manager.hpp" #include "items/projectile_manager.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
@ -69,11 +69,11 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
// Color // Color
mb->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(255, 255, 255, 255))); mb->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 255, 255)));
// Gloss // Gloss
mb->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); mb->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
// Colorization mask // Colorization mask
mb->getMaterial().setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); mb->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
#endif #endif
updatePosition(); updatePosition();
m_node = irr_driver->addMesh(m_mesh, "rubberband"); m_node = irr_driver->addMesh(m_mesh, "rubberband");

View File

@ -23,7 +23,7 @@
#ifdef AI_DEBUG #ifdef AI_DEBUG
# include "graphics/irr_driver.hpp" # include "graphics/irr_driver.hpp"
# include "graphics/texture_manager.hpp" # include "graphics/stk_tex_manager.hpp"
#endif #endif
#include "graphics/show_curve.hpp" #include "graphics/show_curve.hpp"
#include "graphics/slip_stream.hpp" #include "graphics/slip_stream.hpp"
@ -95,8 +95,8 @@ SkiddingAI::SkiddingAI(AbstractKart *kart)
i==2 ? 128 : 0); i==2 ? 128 : 0);
m_debug_sphere[i] = irr_driver->addSphere(1.0f, col_debug); m_debug_sphere[i] = irr_driver->addSphere(1.0f, col_debug);
m_debug_sphere[i]->setVisible(false); m_debug_sphere[i]->setVisible(false);
m_debug_sphere[i]->setMaterialTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180))); m_debug_sphere[i]->setMaterialTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180)));
m_debug_sphere[i]->setMaterialTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m_debug_sphere[i]->setMaterialTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
} }
m_debug_sphere[m_point_selection_algorithm]->setVisible(true); m_debug_sphere[m_point_selection_algorithm]->setVisible(true);
m_item_sphere = irr_driver->addSphere(1.0f, video::SColor(255, 0, 255, 0)); m_item_sphere = irr_driver->addSphere(1.0f, video::SColor(255, 0, 255, 0));

View File

@ -23,7 +23,7 @@
#ifdef AI_DEBUG #ifdef AI_DEBUG
# include "graphics/irr_driver.hpp" # include "graphics/irr_driver.hpp"
# include "graphics/texture_manager.hpp" # include "graphics/stk_tex_manager.hpp"
#endif #endif
#include "graphics/show_curve.hpp" #include "graphics/show_curve.hpp"
#include "graphics/slip_stream.hpp" #include "graphics/slip_stream.hpp"
@ -101,8 +101,8 @@ SkiddingAI::SkiddingAI(AbstractKart *kart)
i==2 ? 128 : 0); i==2 ? 128 : 0);
m_debug_sphere[i] = irr_driver->addSphere(1.0f, col_debug); m_debug_sphere[i] = irr_driver->addSphere(1.0f, col_debug);
m_debug_sphere[i]->setVisible(false); m_debug_sphere[i]->setVisible(false);
m_debug_sphere[i]->setMaterialTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180))); m_debug_sphere[i]->setMaterialTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180)));
m_debug_sphere[i]->setMaterialTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m_debug_sphere[i]->setMaterialTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
} }
m_debug_sphere[m_point_selection_algorithm]->setVisible(true); m_debug_sphere[m_point_selection_algorithm]->setVisible(true);
m_item_sphere = irr_driver->addSphere(1.0f, video::SColor(255, 0, 255, 0)); m_item_sphere = irr_driver->addSphere(1.0f, video::SColor(255, 0, 255, 0));

View File

@ -23,7 +23,7 @@
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/cached_characteristic.hpp" #include "karts/cached_characteristic.hpp"
#include "karts/combined_characteristic.hpp" #include "karts/combined_characteristic.hpp"
@ -225,8 +225,9 @@ void KartProperties::load(const std::string &filename, const std::string &node)
// Load material // Load material
std::string materials_file = m_root+"materials.xml"; std::string materials_file = m_root+"materials.xml";
file_manager->pushModelSearchPath (m_root); std::string unique_id = StringUtils::insertValues("karts/%s", m_ident.c_str());
file_manager->pushTextureSearchPath(m_root); file_manager->pushModelSearchPath(m_root);
file_manager->pushTextureSearchPath(m_root, unique_id);
irr_driver->setTextureErrorMessage("Error while loading kart '%s':", irr_driver->setTextureErrorMessage("Error while loading kart '%s':",
m_name); m_name);
@ -252,7 +253,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (m_minimap_icon == NULL) if (m_minimap_icon == NULL)
{ {
m_minimap_icon = getUnicolorTexture(m_color); m_minimap_icon = STKTexManager::getInstance()->getUnicolorTexture(m_color);
} }
#endif #endif

View File

@ -1574,7 +1574,7 @@ int main(int argc, char *argv[] )
// Both item_manager and powerup_manager load models and therefore // Both item_manager and powerup_manager load models and therefore
// textures from the model directory. To avoid reading the // textures from the model directory. To avoid reading the
// materials.xml twice, we do this here once for both: // materials.xml twice, we do this here once for both:
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,"")); file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""), "models");
const std::string materials_file = const std::string materials_file =
file_manager->getAsset(FileManager::MODEL,"materials.xml"); file_manager->getAsset(FileManager::MODEL,"materials.xml");
if(materials_file!="") if(materials_file!="")

View File

@ -25,6 +25,7 @@
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp" #include "graphics/render_info.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
@ -325,10 +326,18 @@ void SoccerWorld::initKartList()
const unsigned int kart_amount = (unsigned int)m_karts.size(); const unsigned int kart_amount = (unsigned int)m_karts.size();
//Loading the indicator textures //Loading the indicator textures
irr::video::ITexture *red = std::string red_path =
irr_driver->getTexture(FileManager::GUI, "soccer_player_red.png"); file_manager->getAsset(FileManager::GUI, "soccer_player_red.png");
irr::video::ITexture *blue = std::string blue_path =
irr_driver->getTexture(FileManager::GUI, "soccer_player_blue.png"); file_manager->getAsset(FileManager::GUI, "soccer_player_blue.png");
video::ITexture* red = STKTexManager::getInstance()->getTexture
(red_path, true/*srgb*/, true/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
video::ITexture* blue = STKTexManager::getInstance()->getTexture
(blue_path, true/*srgb*/, true/*premul_alpha*/, false/*set_material*/,
true/*mesh_tex*/);
//Assigning indicators //Assigning indicators
for(unsigned int i = 0; i < kart_amount; i++) for(unsigned int i = 0; i < kart_amount; i++)

View File

@ -22,6 +22,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "karts/controller/spare_tire_ai.hpp" #include "karts/controller/spare_tire_ai.hpp"
@ -176,8 +177,12 @@ void ThreeStrikesBattle::kartAdded(AbstractKart* kart, scene::ISceneNode* node)
if (kart->getType() == RaceManager::KartType::KT_SPARE_TIRE) if (kart->getType() == RaceManager::KartType::KT_SPARE_TIRE)
{ {
// Add heart billboard above it // Add heart billboard above it
video::ITexture *heart = std::string heart_path =
irr_driver->getTexture(FileManager::GUI, "heart.png"); file_manager->getAsset(FileManager::GUI, "heart.png");
video::ITexture* heart = STKTexManager::getInstance()->getTexture
(heart_path, true/*srgb*/, true/*premul_alpha*/,
false/*set_material*/, true/*mesh_tex*/);
float height = kart->getKartHeight() + 0.5f; float height = kart->getKartHeight() + 0.5f;
scene::ISceneNode* billboard = irr_driver->addBillboard scene::ISceneNode* billboard = irr_driver->addBillboard

View File

@ -20,7 +20,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "modes/linear_world.hpp" #include "modes/linear_world.hpp"
@ -103,9 +103,9 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
: video::SColor(128, 128, 128, 128); : video::SColor(128, 128, 128, 128);
} }
buffer->recalculateBoundingBox(); buffer->recalculateBoundingBox();
buffer->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180))); buffer->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(128, 255, 105, 180)));
buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); buffer->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
buffer->getMaterial().setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); buffer->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
buffer->getMaterial().BackfaceCulling = false; buffer->getMaterial().BackfaceCulling = false;
//mesh->setBoundingBox(buffer->getBoundingBox()); //mesh->setBoundingBox(buffer->getBoundingBox());
m_debug_node = irr_driver->addMesh(mesh, "checkdebug"); m_debug_node = irr_driver->addMesh(mesh, "checkdebug");
@ -153,7 +153,7 @@ void CheckLine::changeDebugColor(bool is_active)
vertices[i].Color = color; vertices[i].Color = color;
} }
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
buffer->getMaterial().setTexture(0, getUnicolorTexture(color)); buffer->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(color));
#endif #endif
} // changeDebugColor } // changeDebugColor

View File

@ -21,7 +21,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_target.hpp" #include "graphics/render_target.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "graphics/vao_manager.hpp" #include "graphics/vao_manager.hpp"
#include "modes/profile_world.hpp" #include "modes/profile_world.hpp"
#include "tracks/arena_node_3d.hpp" #include "tracks/arena_node_3d.hpp"
@ -108,9 +108,9 @@ void Graph::createMesh(bool show_invisible, bool enable_transparency,
m.Lighting = false; m.Lighting = false;
if (enable_transparency) if (enable_transparency)
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m.setTexture(0, getUnicolorTexture(video::SColor(255, 255, 255, 255))); m.setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 255, 255)));
m.setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m.setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
m.setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); m.setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
m_mesh = irr_driver->createQuadMesh(&m); m_mesh = irr_driver->createQuadMesh(&m);
m_mesh_buffer = m_mesh->getMeshBuffer(0); m_mesh_buffer = m_mesh->getMeshBuffer(0);
assert(m_mesh_buffer->getVertexType()==video::EVT_STANDARD); assert(m_mesh_buffer->getVertexType()==video::EVT_STANDARD);

View File

@ -39,7 +39,7 @@
#include "graphics/particle_kind.hpp" #include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/render_target.hpp" #include "graphics/render_target.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "graphics/vao_manager.hpp" #include "graphics/vao_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
@ -294,13 +294,8 @@ void Track::cleanup()
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
VAOManager::kill(); VAOManager::kill();
ParticleKindManager::get()->cleanUpTrackSpecificGfx(); ParticleKindManager::get()->cleanUpTrackSpecificGfx();
// Clear reminder of transformed textures
resetTextureTable();
#endif #endif
// Clear reminder of the link between textures and file names.
irr_driver->clearTexturesFileName();
for (unsigned int i = 0; i < m_animated_textures.size(); i++) for (unsigned int i = 0; i < m_animated_textures.size(); i++)
{ {
delete m_animated_textures[i]; delete m_animated_textures[i];
@ -411,6 +406,7 @@ void Track::cleanup()
irr_driver->clearLights(); irr_driver->clearLights();
irr_driver->clearForcedBloom(); irr_driver->clearForcedBloom();
irr_driver->clearBackgroundNodes(); irr_driver->clearBackgroundNodes();
STKTexManager::getInstance()->reset();
if(UserConfigParams::logMemory()) if(UserConfigParams::logMemory())
{ {
@ -808,14 +804,14 @@ void Track::createPhysicsModel(unsigned int main_track_count)
// Color // Color
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
mb->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(255, 255, 105, 180))); mb->getMaterial().setTexture(0, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(255, 255, 105, 180)));
#endif #endif
irr_driver->grabAllTextures(mesh); irr_driver->grabAllTextures(mesh);
// Gloss // Gloss
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
mb->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0))); mb->getMaterial().setTexture(1, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
// Colorization mask // Colorization mask
mb->getMaterial().setTexture(2, getUnicolorTexture(video::SColor(0, 0, 0, 0))); mb->getMaterial().setTexture(2, STKTexManager::getInstance()->getUnicolorTexture(video::SColor(0, 0, 0, 0)));
#endif #endif
} }
else else
@ -1632,9 +1628,11 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
m_sky_type = SKY_NONE; m_sky_type = SKY_NONE;
m_track_object_manager = new TrackObjectManager(); m_track_object_manager = new TrackObjectManager();
std::string unique_id = StringUtils::insertValues("tracks/%s", m_ident.c_str());
// Add the track directory to the texture search path // Add the track directory to the texture search path
file_manager->pushTextureSearchPath(m_root); file_manager->pushTextureSearchPath(m_root, unique_id);
file_manager->pushModelSearchPath (m_root); file_manager->pushModelSearchPath(m_root);
// For now ignore the resize cache, since atm it only handles texturs in // For now ignore the resize cache, since atm it only handles texturs in
// the track directory. // the track directory.
@ -1812,7 +1810,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// Sky dome and boxes support // Sky dome and boxes support
// -------------------------- // --------------------------
irr_driver->suppressSkyBox(); irr_driver->suppressSkyBox();
if(m_sky_type==SKY_DOME && m_sky_textures.size() > 0) #ifndef SERVER_ONLY
if(!CVS->isGLSL() && m_sky_type==SKY_DOME && m_sky_textures.size() > 0)
{ {
scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0], scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0],
m_sky_hori_segments, m_sky_hori_segments,
@ -1844,6 +1843,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
{ {
irr_driver->setClearbackBufferColor(m_sky_color); irr_driver->setClearbackBufferColor(m_sky_color);
} }
#endif
// ---- Set ambient color // ---- Set ambient color
m_ambient_color = m_default_ambient_color; m_ambient_color = m_default_ambient_color;
@ -1942,7 +1942,21 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
} }
irr_driver->unsetTextureErrorMessage(); irr_driver->unsetTextureErrorMessage();
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
for (video::ITexture* t : m_sky_textures)
{
t->drop();
}
m_sky_textures.clear();
for (video::ITexture* t : m_spherical_harmonics_textures)
{
t->drop();
}
m_spherical_harmonics_textures.clear();
}
#endif // !SERVER_ONLY
} // loadTrackModel } // loadTrackModel
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2194,10 +2208,26 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
std::vector<std::string> v = StringUtils::split(s, ' '); std::vector<std::string> v = StringUtils::split(s, ' ');
for(unsigned int i=0; i<v.size(); i++) for(unsigned int i=0; i<v.size(); i++)
{ {
video::ITexture *t = irr_driver->getTexture(v[i]); video::ITexture* t = NULL;
if(t) #ifndef SERVER_ONLY
if (CVS->isGLSL())
{ {
t->grab(); t = STKTexManager::getInstance()->getTexture(v[i],
false/*srgb*/, false/*premul_alpha*/,
false/*set_material*/, false/*mesh_tex*/,
true/*no_upload*/);
}
else
#endif // !SERVER_ONLY
{
t = irr_driver->getTexture(v[i]);
}
if (t)
{
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
#endif // !SERVER_ONLY
t->grab();
m_sky_textures.push_back(t); m_sky_textures.push_back(t);
} }
else else
@ -2224,10 +2254,26 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
v = StringUtils::split(sh_textures, ' '); v = StringUtils::split(sh_textures, ' ');
for (unsigned int i = 0; i<v.size(); i++) for (unsigned int i = 0; i<v.size(); i++)
{ {
video::ITexture *t = irr_driver->getTexture(v[i]); video::ITexture* t = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
t = STKTexManager::getInstance()->getTexture(v[i],
false/*srgb*/, false/*premul_alpha*/,
false/*set_material*/, false/*mesh_tex*/,
true/*no_upload*/);
}
else
#endif // !SERVER_ONLY
{
t = irr_driver->getTexture(v[i]);
}
if (t) if (t)
{ {
t->grab(); #ifndef SERVER_ONLY
if (!CVS->isGLSL())
#endif // !SERVER_ONLY
t->grab();
m_spherical_harmonics_textures.push_back(t); m_spherical_harmonics_textures.push_back(t);
} }
else else

View File

@ -31,6 +31,7 @@
#include "graphics/particle_emitter.hpp" #include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/stk_mesh_scene_node.hpp" #include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "graphics/render_info.hpp" #include "graphics/render_info.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
@ -231,7 +232,8 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
return; return;
} }
file_manager->pushTextureSearchPath(lib_path + "/"); std::string unique_id = StringUtils::insertValues("library/%s", name.c_str());
file_manager->pushTextureSearchPath(lib_path + "/", unique_id);
file_manager->pushModelSearchPath(lib_path); file_manager->pushModelSearchPath(lib_path);
material_manager->pushTempMaterial(lib_path + "/materials.xml"); material_manager->pushTempMaterial(lib_path + "/materials.xml");
model_def_loader.addToLibrary(name, libroot); model_def_loader.addToLibrary(name, libroot);
@ -437,7 +439,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
World::getWorld()->getIdent() == IDENT_CUTSCENE); World::getWorld()->getIdent() == IDENT_CUTSCENE);
m_model_file = model_file; m_model_file = model_file;
file_manager->pushTextureSearchPath(StringUtils::getPath(model_file)); //file_manager->pushTextureSearchPath(StringUtils::getPath(model_file));
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (file_manager->fileExists(model_file)) if (file_manager->fileExists(model_file))
{ {
@ -465,7 +467,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
throw std::runtime_error("Model '" + model_file + "' cannot be found"); throw std::runtime_error("Model '" + model_file + "' cannot be found");
} }
file_manager->popTextureSearchPath(); //file_manager->popTextureSearchPath();
init(NULL, NULL, true); init(NULL, NULL, true);
} // TrackObjectPresentationMesh } // TrackObjectPresentationMesh
@ -830,9 +832,10 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(
xml_node.get("start", &m_fade_out_start); xml_node.get("start", &m_fade_out_start);
xml_node.get("end", &m_fade_out_end ); xml_node.get("end", &m_fade_out_end );
} }
video::ITexture* texture = STKTexManager::getInstance()->getTexture
(file_manager->searchTexture(texture_name), true/*srgb*/,
true/*premul_alpha*/, false/*set_material*/, true/*mesh_tex*/);
video::ITexture* texture =
irr_driver->getTexture(file_manager->searchTexture(texture_name));
if (texture == NULL) if (texture == NULL)
{ {
Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found", Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found",

View File

@ -29,7 +29,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/light.hpp" #include "graphics/light.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/texture_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp" #include "guiengine/widgets/text_box_widget.hpp"
#include "items/powerup_manager.hpp" #include "items/powerup_manager.hpp"
@ -133,7 +133,7 @@ enum DebugMenuCommand
DEBUG_ADJUST_LIGHTS, DEBUG_ADJUST_LIGHTS,
DEBUG_SCRIPT_CONSOLE, DEBUG_SCRIPT_CONSOLE,
DEBUG_RUN_CUTSCENE, DEBUG_RUN_CUTSCENE,
DEBUG_RELOAD_TEXTURE, DEBUG_TEXTURE_CONSOLE,
}; // DebugMenuCommand }; // DebugMenuCommand
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -687,15 +687,24 @@ bool handleContextMenuAction(s32 cmd_id)
((CutsceneWorld*)World::getWorld())->setParts(parts); ((CutsceneWorld*)World::getWorld())->setParts(parts);
}); });
break; break;
case DEBUG_RELOAD_TEXTURE: case DEBUG_TEXTURE_CONSOLE:
new GeneralTextFieldDialog( new GeneralTextFieldDialog(
L"Enter the texture filename(s) (separate names by ;)" L"Enter the texture filename(s) (separate names by ;)"
" to be reloaded (empty to reload all)", [] " to be reloaded (empty to reload all)\n"
"Press tus; for texture usage stats (shown in console)", []
(const irr::core::stringw& text) {}, (const irr::core::stringw& text) {},
[] (GUIEngine::LabelWidget* lw, GUIEngine::TextBoxWidget* tb)->bool [] (GUIEngine::LabelWidget* lw, GUIEngine::TextBoxWidget* tb)->bool
{ {
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
lw->setText(reloadTexture(tb->getText()), true); core::stringw t = tb->getText();
STKTexManager* stktm = STKTexManager::getInstance();
if (t == "tus;")
{
stktm->dumpAllTexture(false/*mesh_texture*/);
stktm->dumpTextureUsage();
return false;
}
lw->setText(stktm->reloadTexture(t), true);
#endif #endif
// Don't close the dialog after each run // Don't close the dialog after each run
return false; return false;
@ -809,7 +818,7 @@ bool onEvent(const SEvent &event)
mnu->addItem(L"Adjust Lights", DEBUG_ADJUST_LIGHTS); mnu->addItem(L"Adjust Lights", DEBUG_ADJUST_LIGHTS);
mnu->addItem(L"Scripting console", DEBUG_SCRIPT_CONSOLE); mnu->addItem(L"Scripting console", DEBUG_SCRIPT_CONSOLE);
mnu->addItem(L"Run cutscene(s)", DEBUG_RUN_CUTSCENE); mnu->addItem(L"Run cutscene(s)", DEBUG_RUN_CUTSCENE);
mnu->addItem(L"Reload texture", DEBUG_RELOAD_TEXTURE); mnu->addItem(L"Texture console", DEBUG_TEXTURE_CONSOLE);
g_debug_menu_visible = true; g_debug_menu_visible = true;
irr_driver->showPointer(); irr_driver->showPointer();