/** * \file neltexture.cpp * \date November 2004 * \author Matt Raykowski * \author Henri Kuuste */ // NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . /************************************************************************ purpose: Implementation for main Nevrax Engine GUI texture class For use with GUI Library: Crazy Eddie's GUI System (http://crayzedsgui.sourceforge.net) Copyright (C)2004 Paul D Turner (crayzed@users.sourceforge.net) This file contains code that is specific to NeL (http://www.nevrax.org) *************************************************************************/ // NeL Renderer includes #include #include // CEGUI includes #include "CEGUIExceptions.h" // ditch min/max, they mess stuff up. #undef max #undef min //nel includes #include #include #include #include namespace CEGUI { NeLTexture::NeLTexture(Renderer *owner) : Texture(owner) { m_Owner=dynamic_cast(owner); m_Material = m_Owner->getNeLDriver().createMaterial(); m_TextureFile=NULL; m_TextureMem=NULL; m_UsingFile=false; m_UsingMem=false; } NeLTexture::~NeLTexture(void) { freeNeLTexture(); // can't free material in the same phase as the texture. m_Owner->getNeLDriver().deleteMaterial(m_Material); m_Material=NULL; } void NeLTexture::loadFromFile(const String &filename, const String& resourceGroup) { String file = NLMISC::CPath::lookup(filename.c_str()).c_str(); // this object can only contain one texture at a time, free the old one if it exists. freeNeLTexture(); // create the texture from a file... /* TODO: Determine if Kervala was correct in removing setWrapS/T */ m_TextureFile=m_Owner->getNeLDriver().createTextureFile(file.c_str()); m_TextureFile->setWrapS(NL3D::UTexture::Clamp); m_TextureFile->setWrapT(NL3D::UTexture::Clamp); if(m_TextureFile == 0) { // failed to load the texture. nlinfo("Failed to load texture: %s",filename.c_str()); return; } // because nel unloads the texture from RAM when it loads it into VRAM // we need to load the texture into a bitmap to get the sizes. NL3D::CBitmap tmpBitmap; NLMISC::CIFile nelfile(file.c_str()); tmpBitmap.load(nelfile); d_width=tmpBitmap.getWidth(); d_height=tmpBitmap.getHeight(); // set the material up. m_UsingFile=true; m_UsingMem=false; m_Material.setTexture(m_TextureFile); m_Material.setBlend(true); m_Material.setBlendFunc(NL3D::UMaterial::srcalpha, NL3D::UMaterial::invsrcalpha); m_Material.setAlphaTest(false); m_Material.setZFunc(NL3D::UMaterial::always); m_Material.setDoubleSided(); } void NeLTexture::loadFromMemory(const void *buffPtr, uint buffWidth, uint buffHeight, PixelFormat pixelFormat) { // this object can only contain one texture at a time, free the old one if it exists. freeNeLTexture(); /** * This debugging is handy when you're not sure if the memory buffer * being sent to you from CEGUI is valid. Uncomment it and it'll create * a file called loadfrommem###.tga in your working directory. * * NLMISC::CBitmap btm; * btm.reset(); * btm.resize(buffWidth,buffHeight,NLMISC::CBitmap::RGBA); * uint8 *dest=&(btm.getPixels()[0]); * memcpy(dest,buffPtr,buffWidth*buffHeight*4); * std::string filename = NLMISC::CFile::findNewFile("loadfrommem.tga"); * NLMISC::COFile fs(filename); * btm.writeTGA(fs); */ int size=4; switch(pixelFormat) { case PF_RGB: size = 3; break; case PF_RGBA: size = 4; break; } // copy the memory stream for use in the NeL texture. uint8 *pTmpBuf=new uint8[buffWidth*buffHeight*size]; memcpy(pTmpBuf,buffPtr,buffWidth*buffHeight*size); // create the texture m_TextureMem=new NL3D::CTextureMem( pTmpBuf,buffWidth*buffHeight*size,true,false,buffWidth,buffHeight,NLMISC::CBitmap::RGBA); m_TextureMem->setWrapS(NL3D::ITexture::Clamp); m_TextureMem->setWrapT(NL3D::ITexture::Clamp); m_TextureMem->setFilterMode(NL3D::ITexture::Linear, NL3D::ITexture::LinearMipMapOff); m_TextureMem->setReleasable(false); m_TextureMem->generate(); if(m_TextureMem == 0) { // failed to load the texture. nlinfo("Failed to load texture from memory"); return; } /** * Configure the material. This is a little more complicated than loading a texture from * a file, since CTextureFileUser and CTextureFile take care of prepping all of the * necessary alpha settings. */ NL3D::CMaterial *mat = m_Material.getObjectPtr(); mat->initUnlit(); mat->setShader(NL3D::CMaterial::Normal); mat->setTexture(0, m_TextureMem); /** * We still use alpha testing to cull out pixels to speed up * blending and multitexturing. */ m_Material.setAlphaTest(true); m_Material.setAlphaTestThreshold(0.1f); m_Material.setBlend(true); m_Material.setBlendFunc(NL3D::UMaterial::srcalpha,NL3D::UMaterial::invsrcalpha); m_Material.texEnvOpRGB(0, NL3D::UMaterial::Modulate); m_Material.texEnvArg0RGB(0, NL3D::UMaterial::Texture, NL3D::UMaterial::SrcColor); m_Material.texEnvArg1RGB(0, NL3D::UMaterial::Diffuse, NL3D::UMaterial::SrcColor); m_Material.texEnvOpAlpha(0, NL3D::UMaterial::Modulate); m_Material.texEnvArg0Alpha(0, NL3D::UMaterial::Texture, NL3D::UMaterial::SrcAlpha); m_Material.texEnvArg1Alpha(0, NL3D::UMaterial::Diffuse, NL3D::UMaterial::SrcAlpha); m_Material.setZFunc(NL3D::UMaterial::always); m_Material.setDoubleSided(true); // make sure to record our changes. d_width=buffWidth; d_height=buffHeight; m_UsingFile=false; m_UsingMem=true; } NL3D::UMaterial NeLTexture::getNeLTexture(void) { return m_Material; } void NeLTexture::freeNeLTexture(void) { // never been populated. if(m_TextureMem==NULL && m_TextureFile==NULL) return; if(m_UsingFile==true) { m_Owner->getNeLDriver().deleteTextureFile(m_TextureFile); m_TextureFile=NULL; m_UsingFile=false; } else if(m_UsingMem==true) { //m_Owner->getNeLDriver().deleteTextureMem(m_TextureMem); m_TextureMem=NULL; m_UsingMem=false; } else { nlwarning("Something has gone horribly wrong, unable to free any type of texture."); } } } // end namespace CEGUI