Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qstringlist.h></qstringlist.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tsimplecolorstyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttessellator.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "trandom.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagestyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
//    TTextureStyle  implementation
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRandom Random;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define QUAD_PRIMITIVE GL_QUAD_STRIP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::pair<tpointd, tpointd=""> PointPair;</tpointd,>
Toshihiro Shimizu 890ddd
typedef std::vector<tpointd> PointArray;</tpointd>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
PointPair computeTexParameters(const TPointD &p1, const TPointD &p2,
Shinya Kitaoka 120a6e
                               const TPointD &tex1, const TPointD &tex2,
Shinya Kitaoka 120a6e
                               const PointPair &newP, const TDimension &size) {
Shinya Kitaoka 120a6e
  // texture points
Shinya Kitaoka 120a6e
  static PointPair tex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // set vector of movement
Shinya Kitaoka 120a6e
  TPointD v = (newP.first + newP.second) * 0.5 - (p2 + p1) * 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // compute length of opposite segment
MCCCS a0ce32
  double lengthNextP1NextP2 = tdistance(newP.first, newP.second);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // compute parameter texture offset starting from 0.5
MCCCS a0ce32
  double texParameterOffset = lengthNextP1NextP2 / size.lx * 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // fix value for s
Shinya Kitaoka 120a6e
  tex.first.x  = 0.5 - texParameterOffset;
Shinya Kitaoka 120a6e
  tex.second.x = 0.5 + texParameterOffset;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // get length
Shinya Kitaoka 120a6e
  double disty = norm(v);
Shinya Kitaoka 120a6e
  assert(tex1.y == tex2.y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // find parameter for t
Shinya Kitaoka 120a6e
  texParameterOffset = disty / size.ly;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // fix values for t (oldValue + newValue)
Shinya Kitaoka 120a6e
  tex.first.y = tex.second.y = tex1.y + texParameterOffset;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return tex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void setTexCoords(const TPointD tex, TOutlinePoint &p) {
Shinya Kitaoka 120a6e
  p.u = tex.x;
Shinya Kitaoka 120a6e
  p.v = tex.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD getTexCoords(const TOutlinePoint &p) { return TPointD(p.u, p.v); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
TTextureStyle::TTextureStyle(const TRasterP &ras, const TFilePath &texturePath)
Shinya Kitaoka 120a6e
    : m_texture(ras)
Shinya Kitaoka 120a6e
    , m_texturePath(texturePath)
Shinya Kitaoka 120a6e
    , m_tessellator(new TglTessellator)
Shinya Kitaoka 120a6e
    , m_params()
Shinya Kitaoka 120a6e
    , m_texturePathLoaded() {
Shinya Kitaoka 120a6e
  setAverageColor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath TImageStyle::m_libraryDir;
Toshihiro Shimizu 890ddd
ToonzScene *TImageStyle::m_currentScene = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TTextureStyle::TTextureStyle(const TTextureStyle &other)
Shinya Kitaoka 120a6e
    : TOutlineStyle(other)
Shinya Kitaoka 120a6e
    , TRasterStyleFx(other)
Shinya Kitaoka 120a6e
    , TImageStyle(other)
Shinya Kitaoka 120a6e
    , m_texture(other.m_texture)
Shinya Kitaoka 120a6e
    , m_texturePath(other.m_texturePath)
Shinya Kitaoka 120a6e
    , m_texturePathLoaded(other.m_texturePathLoaded)
Shinya Kitaoka 120a6e
    , m_params(other.m_params)
Shinya Kitaoka 120a6e
    , m_tessellator(new TglTessellator) {
Shinya Kitaoka 120a6e
  setAverageColor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTextureStyle::~TTextureStyle() { delete m_tessellator; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle *TTextureStyle::clone() const { return new TTextureStyle(*this); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString TTextureStyle::getDescription() const { return "TextureStyle"; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
int TTextureStyle::getTagId() const { return 4; }
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterP TTextureStyle::getTexture() const { return m_texture; }
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setAverageColor() {
Shinya Kitaoka 120a6e
  loadTextureRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P r32 = (TRaster32P)m_texture;
Shinya Kitaoka 120a6e
  if (!r32) {
Shinya Kitaoka 120a6e
    m_averageColor = TPixel::Black;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_params.m_isPattern) {
Shinya Kitaoka 120a6e
    m_averageColor = m_params.m_patternColor;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TPixelD color(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  r32->lock();
Shinya Kitaoka 120a6e
  for (int i = 0; i < r32->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel32 *buf = r32->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < r32->getLx(); j++, buf++) {
Shinya Kitaoka 120a6e
      color.r += buf->r;
Shinya Kitaoka 120a6e
      color.g += buf->g;
Shinya Kitaoka 120a6e
      color.b += buf->b;
Shinya Kitaoka 120a6e
      color.m += buf->m;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r32->unlock();
Shinya Kitaoka 120a6e
  int pixels       = r32->getLx() * r32->getLy();
Shinya Kitaoka 120a6e
  m_averageColor.r = (int)(color.r / pixels);
Shinya Kitaoka 120a6e
  m_averageColor.g = (int)(color.g / pixels);
Shinya Kitaoka 120a6e
  m_averageColor.b = (int)(color.b / pixels);
Shinya Kitaoka 120a6e
  m_averageColor.m = (int)(color.m / pixels);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setTexture(const TRasterP &ras) {
Shinya Kitaoka 120a6e
  m_texture = ras;
Shinya Kitaoka 120a6e
  delete m_tessellator;
Shinya Kitaoka 120a6e
  m_tessellator = new TglTessellator;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setAverageColor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TPixel32 TTextureStyle::getAverageColor() const { return m_averageColor; }
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTextureStyle::computeOutline(const TStroke *stroke,
Shinya Kitaoka 120a6e
                                   TStrokeOutline &outline,
Shinya Kitaoka 120a6e
                                   TOutlineUtil::OutlineParameter param) const {
Shinya Kitaoka 120a6e
  TOutlineStyle::computeOutline(stroke, outline, param);
Shinya Kitaoka 120a6e
  std::vector<toutlinepoint> &v = outline.getArray();</toutlinepoint>
Shinya Kitaoka 120a6e
  PointPair newPnt;
Shinya Kitaoka 120a6e
  TDimension size = m_texture->getSize();
Shinya Kitaoka 120a6e
  UINT i          = 0;
Shinya Kitaoka 120a6e
  for (i = 2; i < v.size(); i += 2) {
Shinya Kitaoka 120a6e
    newPnt.first  = convert(v[i]);
Shinya Kitaoka 120a6e
    newPnt.second = convert(v[i + 1]);
Shinya Kitaoka 120a6e
    newPnt        = computeTexParameters(convert(v[i - 2]), convert(v[i - 1]),
Shinya Kitaoka 120a6e
                                  getTexCoords(v[i - 2]),
Shinya Kitaoka 120a6e
                                  getTexCoords(v[i - 1]), newPnt, size);
Shinya Kitaoka 120a6e
    setTexCoords(newPnt.first, v[i]);
Shinya Kitaoka 120a6e
    setTexCoords(newPnt.second, v[i + 1]);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (i = 0; i < v.size(); i++) {
Shinya Kitaoka 120a6e
    v[i].u = (i & 1) == 0 ? 0 : 1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TTextureStyle::drawStroke(const TColorFunction *cf,
Shinya Kitaoka 120a6e
                               TStrokeOutline *outline,
Shinya Kitaoka 120a6e
                               const TStroke *stroke) const {
Shinya Kitaoka 120a6e
  /*struct locals {
Shinya Kitaoka 120a6e
static float adaptToGLTextureFunction( USHORT style )
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
switch( style )
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
case TTextureStyle::DECAL:
Shinya Kitaoka 120a6e
  return GL_DECAL;
Shinya Kitaoka 120a6e
  break;
Shinya Kitaoka 120a6e
case TTextureStyle::MODULATE:
Shinya Kitaoka 120a6e
  return GL_MODULATE;
Shinya Kitaoka 120a6e
  break;
Shinya Kitaoka 120a6e
case TTextureStyle::BLEND:
Shinya Kitaoka 120a6e
  return GL_BLEND;
Shinya Kitaoka 120a6e
  break;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
return GL_DECAL;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
};    // locals;*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<toutlinepoint> &v = outline->getArray();</toutlinepoint>
Shinya Kitaoka 120a6e
  if (v.empty()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TRasterP texture = m_texture;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(!v.empty() || !texture);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (v.empty() || !texture) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static const int stride = sizeof(TOutlinePoint);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glColor4d(1.0, 1.0, 1.0, 1.0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // information about vertex
Shinya Kitaoka 120a6e
  glEnableClientState(GL_VERTEX_ARRAY);
Shinya Kitaoka 120a6e
  glVertexPointer(2, GL_DOUBLE, stride, &v[0]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  GLboolean blendEnabled;
Shinya Kitaoka 120a6e
  glGetBooleanv(GL_BLEND, &blendEnabled);
Shinya Kitaoka 120a6e
  assert(blendEnabled);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Shinya Kitaoka 120a6e
  glTexCoordPointer(2, GL_DOUBLE, stride, &(v[0].u));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TextureInfoForGL texInfo;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_texture->lock();
Shinya Kitaoka 120a6e
  TRasterP texImage = prepareTexture(m_texture, texInfo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Generate a texture id and bind it.
Shinya Kitaoka 120a6e
  GLuint texId;
Shinya Kitaoka 120a6e
  glGenTextures(1, &texId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glBindTexture(GL_TEXTURE_2D, texId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Specify texture parameters
Shinya Kitaoka 120a6e
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Shinya Kitaoka 120a6e
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Shinya Kitaoka 120a6e
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Shinya Kitaoka 120a6e
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
Shinya Kitaoka 120a6e
            GL_MODULATE);  // change texture blending function
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glPixelStorei(GL_UNPACK_ROW_LENGTH, texImage->getWrap() != texImage->getLx()
Shinya Kitaoka 120a6e
                                          ? texImage->getWrap()
Shinya Kitaoka 120a6e
                                          : 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (texImage != m_texture) texImage->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Load texture
Shinya Kitaoka 120a6e
  glTexImage2D(GL_TEXTURE_2D,
Shinya Kitaoka 120a6e
               0,                       // one level only
Shinya Kitaoka 120a6e
               texInfo.internalformat,  // pixel channels count
Shinya Kitaoka 120a6e
               texInfo.width,           // width
Shinya Kitaoka 120a6e
               texInfo.height,          // height
Shinya Kitaoka 120a6e
               0,                       // border size
Shinya Kitaoka 120a6e
               texInfo.type,    // pixel format           // crappy names
Shinya Kitaoka 120a6e
               texInfo.format,  // pixel data type        // oh, SO much
Shinya Kitaoka 120a6e
               texImage->getRawData());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_texture->unlock();
Shinya Kitaoka 120a6e
  if (texImage != m_texture) texImage->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Step 1: draw outline
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  for (i = 0; i < v.size(); i += 2) glArrayElement(i);
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  for (i = 1; i < v.size(); i += 2) glArrayElement(i);
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Step 2: draw texturized stroke
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
#ifdef MACOSX                   //NON SI CAPISCE PERCHE DRAWARRAY E DISPLAY LIST
Shinya Kitaoka 120a6e
PROVOCHINO UN CRASH SU MAC
Shinya Kitaoka 120a6e
#warning "INDAGARE ANCORA!!!!"  //PER ADESSO CHIEDO SE STA REGISTANDO UNA
Shinya Kitaoka 120a6e
DISPLAYLIST E IN QUEL CASO NON USO GLI ARRAY
Shinya Kitaoka 120a6e
GLuint listId;
Shinya Kitaoka 120a6e
glGetIntegerv(GL_LIST_INDEX,(GLint*)&listId);
Shinya Kitaoka 120a6e
if(listId==0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
#endif
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  glDrawArrays(QUAD_PRIMITIVE, 0, v.size());
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
#ifdef MACOSX
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
else
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
glBegin( GL_QUAD_STRIP );
Shinya Kitaoka 120a6e
for(UINT i=0; i< v.size(); i++)
Shinya Kitaoka 120a6e
glVertex2dv( &v[i].x );
Shinya Kitaoka 120a6e
glEnd();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
#endif
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Delete texture
Shinya Kitaoka 120a6e
  glDeleteTextures(1, &texId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glDisableClientState(GL_VERTEX_ARRAY);
Shinya Kitaoka 120a6e
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Shinya Kitaoka 120a6e
  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
Shinya Kitaoka 120a6e
  glDisable(GL_TEXTURE_2D);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
// drawRegion( const TVectorRenderData &rd,  TRegionOutline &boundary ) const
Shinya Kitaoka 120a6e
void TTextureStyle::drawRegion(const TColorFunction *cf,
Shinya Kitaoka 120a6e
                               const bool antiAliasing,
Shinya Kitaoka 120a6e
                               TRegionOutline &boundary) const {
Shinya Kitaoka 120a6e
  if (m_tessellator)
Shinya Kitaoka 120a6e
    m_tessellator->tessellate(cf, antiAliasing, boundary, m_texture);
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tileRaster(const TRaster32P &tile, const TRaster32P &rout) {
Shinya Kitaoka 120a6e
  int x0, y0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rout->getLy() > tile->getLy())  /// tile must be centered in rout
Shinya Kitaoka 120a6e
    y0 =
Shinya Kitaoka 120a6e
        tile->getLy() - (((rout->getLy() - tile->getLy()) / 2) % tile->getLy());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    y0 = (tile->getLy() - rout->getLy()) / 2;
Shinya Kitaoka 120a6e
  if (rout->getLx() > tile->getLx())  /// tile must be centered in rout
Shinya Kitaoka 120a6e
    x0 =
Shinya Kitaoka 120a6e
        tile->getLx() - (((rout->getLx() - tile->getLx()) / 2) % tile->getLx());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    x0 = (tile->getLx() - rout->getLx()) / 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // x0-=tround(offs.x);
Shinya Kitaoka 120a6e
  // y0-=tround(offs.y);
Shinya Kitaoka 120a6e
  while (x0 < 0) x0 += tile->getLx();
Shinya Kitaoka 120a6e
  while (y0 < 0) y0 += tile->getLy();
Shinya Kitaoka 120a6e
  x0 = x0 % tile->getLx();
Shinya Kitaoka 120a6e
  y0 = y0 % tile->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int y = y0;
Shinya Kitaoka 120a6e
  for (int i = 0; i < rout->getLy(); i++, y++) {
Shinya Kitaoka 120a6e
    if (y == tile->getLy()) y = 0;
Shinya Kitaoka 120a6e
    int x                     = x0;
Shinya Kitaoka 120a6e
    TPixel32 *pixout          = rout->pixels(i);
Shinya Kitaoka 120a6e
    TPixel32 *pixin           = tile->pixels(y) + x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int j = 0; j < rout->getLx(); j++, pixin++, pixout++, x++) {
Shinya Kitaoka 120a6e
      if (x == tile->getLx()) {
Shinya Kitaoka 120a6e
        x = 0, pixin = tile->pixels(y);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      *pixout = *pixin;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void doContrast(double contrast, const TRaster32P &rin) {
Shinya Kitaoka 120a6e
  TPixel32 *row, *pix;
Shinya Kitaoka 120a6e
  int i, j, lx, ly, wrap;
Shinya Kitaoka 120a6e
  double line_avg_r, line_avg_g, line_avg_b;
Shinya Kitaoka 120a6e
  double avg_r = 0, avg_g = 0, avg_b = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  lx   = rin->getLx();
Shinya Kitaoka 120a6e
  ly   = rin->getLy();
Shinya Kitaoka 120a6e
  wrap = rin->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (j = 0, row = (TPixel32 *)rin->getRawData(); j < ly; j++, row += wrap) {
Shinya Kitaoka 120a6e
    line_avg_r = 0;
Shinya Kitaoka 120a6e
    line_avg_g = 0;
Shinya Kitaoka 120a6e
    line_avg_b = 0;
Shinya Kitaoka 120a6e
    for (i = 0, pix = row; i < lx; i++, pix++) {
Shinya Kitaoka 120a6e
      line_avg_r += pix->r;
Shinya Kitaoka 120a6e
      line_avg_g += pix->g;
Shinya Kitaoka 120a6e
      line_avg_b += pix->b;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    avg_r += line_avg_r / lx;
Shinya Kitaoka 120a6e
    avg_g += line_avg_g / lx;
Shinya Kitaoka 120a6e
    avg_b += line_avg_b / lx;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  avg_r /= ly;
Shinya Kitaoka 120a6e
  avg_g /= ly;
Shinya Kitaoka 120a6e
  avg_b /= ly;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int ires;
Shinya Kitaoka 120a6e
  double dres;
Shinya Kitaoka 120a6e
  TPixel32 lut[256];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < 256; i++) {
Shinya Kitaoka 120a6e
    dres     = contrast * (i - avg_r) + avg_r;
Shinya Kitaoka 120a6e
    ires     = tround(dres);
Shinya Kitaoka 120a6e
    lut[i].r = tcrop(ires, 0, 255);
Shinya Kitaoka 120a6e
    dres     = contrast * (i - avg_g) + avg_g;
Shinya Kitaoka 120a6e
    ires     = tround(dres);
Shinya Kitaoka 120a6e
    lut[i].g = tcrop(ires, 0, 255);
Shinya Kitaoka 120a6e
    dres     = contrast * (i - avg_b) + avg_b;
Shinya Kitaoka 120a6e
    ires     = tround(dres);
Shinya Kitaoka 120a6e
    lut[i].b = tcrop(ires, 0, 255);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (j = 0, row = (TPixel32 *)rin->getRawData(); j < ly; j++, row += wrap) {
Shinya Kitaoka 120a6e
    for (i = 0, pix = row; i < lx; i++, pix++) {
Shinya Kitaoka 120a6e
      pix->r = lut[pix->r].r;
Shinya Kitaoka 120a6e
      pix->g = lut[pix->g].g;
Shinya Kitaoka 120a6e
      pix->b = lut[pix->b].b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (pix->r > pix->m) pix->r = pix->m;
Shinya Kitaoka 120a6e
      if (pix->g > pix->m) pix->g = pix->m;
Shinya Kitaoka 120a6e
      if (pix->b > pix->m) pix->b = pix->m;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BYTE_ROUND(A) ((UINT)((A) + (1U << 23)) >> 24)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define MAGICFAC (257U * 256U + 1U)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static void doPattern(const TRaster32P &r, TPixel32 color) {
Shinya Kitaoka 120a6e
  int i, j, fac = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TPixelGR8::from(color).value < 128)
Shinya Kitaoka 120a6e
    fac = 255 - color.m * (255.0 - color.m) / 255.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPixel32 *buf;
Shinya Kitaoka 120a6e
  UINT b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < r->getLy(); i++) {
Shinya Kitaoka 120a6e
    buf = (TPixel32 *)r->pixels(i);
Shinya Kitaoka 120a6e
    for (j = 0; j < r->getLx(); j++, buf++) {
Shinya Kitaoka 120a6e
      if (buf->m > 0) {
Shinya Kitaoka 120a6e
        b = TPixelGR8::from(*buf).value * MAGICFAC;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        buf->r = BYTE_ROUND(b * color.r + fac);
Shinya Kitaoka 120a6e
        buf->g = BYTE_ROUND(b * color.g + fac);
Shinya Kitaoka 120a6e
        buf->b = BYTE_ROUND(b * color.b + fac);
Shinya Kitaoka 120a6e
        if (buf->m < 255 || color.m < 255) {
Shinya Kitaoka 120a6e
          buf->m = BYTE_ROUND(buf->m * color.m / 255.0);
Shinya Kitaoka 120a6e
          premult(*buf);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          buf->m = 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void applyTexture(const TRaster32P &rTex, const TRaster32P &r, TPoint p) {
Shinya Kitaoka 120a6e
  while (p.x < 0) p.x += rTex->getLx();
Shinya Kitaoka 120a6e
  while (p.y < 0) p.y += rTex->getLy();
Shinya Kitaoka 120a6e
  r->lock();
Shinya Kitaoka 120a6e
  rTex->lock();
Shinya Kitaoka 120a6e
  for (int y = 0, yTex = p.y; y < r->getLy(); y++, yTex++) {
Shinya Kitaoka 120a6e
    TPixel32 *pixIn = r->pixels(y);
Shinya Kitaoka 120a6e
    if (yTex >= rTex->getLy()) yTex -= rTex->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPixel32 *pixTex = (TPixel32 *)(rTex->pixels(yTex)) + p.x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int x = 0, xTex = p.x; x < r->getLx();
Shinya Kitaoka 120a6e
         x++, xTex++, pixIn++, pixTex++) {
Shinya Kitaoka 120a6e
      if (xTex >= rTex->getLx()) xTex -= rTex->getLx(), pixTex -= rTex->getLx();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (pixIn->m == 0) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (pixIn->m == 255)
Shinya Kitaoka 120a6e
        *pixIn = *pixTex;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        pixIn->r = pixIn->m * pixTex->r / 255;
Shinya Kitaoka 120a6e
        pixIn->g = pixIn->m * pixTex->g / 255;
Shinya Kitaoka 120a6e
        pixIn->b = pixIn->m * pixTex->b / 255;
Shinya Kitaoka 120a6e
        pixIn->m = pixIn->m * pixTex->m / 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r->unlock();
Shinya Kitaoka 120a6e
  rTex->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint computeCentroid(const TRaster32P &r);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TTextureStyle::getParamCount() const { return 8; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString TTextureStyle::getParamNames(int index) const {
Shinya Kitaoka 120a6e
  switch (index) {
Shinya Kitaoka 120a6e
  case 0:
Shinya Kitaoka 120a6e
    return "Use As Pattern";
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    return "Position";
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    return "Scale";
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    return "Rotation(degrees)";
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    return "X displ";
Shinya Kitaoka 120a6e
  case 5:
Shinya Kitaoka 120a6e
    return "Y displ";
Shinya Kitaoka 120a6e
  case 6:
Shinya Kitaoka 120a6e
    return "Contrast";
Shinya Kitaoka 120a6e
  case 7:
Shinya Kitaoka 120a6e
    return "Load From File";
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return QString("");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::getParamRange(int index, double &min, double &max) const {
Shinya Kitaoka 120a6e
  assert(index > 1);
Shinya Kitaoka 120a6e
  switch (index) {
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    min = 0.15;
Shinya Kitaoka 120a6e
    max = 10;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    min = -180;
Shinya Kitaoka 120a6e
    max = 180;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    min = -500;
Shinya Kitaoka 120a6e
    max = 500;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 5:
Shinya Kitaoka 120a6e
    min = -500;
Shinya Kitaoka 120a6e
    max = 500;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 6:
Shinya Kitaoka 120a6e
    min = 0.01;
Shinya Kitaoka 120a6e
    max = 10;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle::ParamType TTextureStyle::getParamType(int index) const {
Shinya Kitaoka 120a6e
  assert(0 <= index && index < getParamCount());
Shinya Kitaoka 120a6e
  if (index == 0)
Shinya Kitaoka 120a6e
    return TColorStyle::BOOL;
Shinya Kitaoka 120a6e
  else if (index == 1)
Shinya Kitaoka 120a6e
    return TColorStyle::ENUM;
Shinya Kitaoka 120a6e
  else if (index == 7)
Shinya Kitaoka 120a6e
    return TColorStyle::FILEPATH;
Shinya Kitaoka 120a6e
  return TColorStyle::DOUBLE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::getParamRange(int index, QStringList &enumItems) const {
Shinya Kitaoka 120a6e
  assert(index == 1 || index == 7);
Shinya Kitaoka 120a6e
  if (index == 1)
Shinya Kitaoka 120a6e
    enumItems << "FIXED"
Shinya Kitaoka 120a6e
              << "AUTOMATIC"
Shinya Kitaoka 120a6e
              << "RANDOM";
Shinya Kitaoka 120a6e
  else if (index == 7)
Shinya Kitaoka 120a6e
    enumItems << "bmp"
Shinya Kitaoka 120a6e
              << "jpg"
Shinya Kitaoka 120a6e
              << "png"
Shinya Kitaoka 120a6e
              << "tif"
Shinya Kitaoka 120a6e
              << "tiff"
Shinya Kitaoka 120a6e
              << "gif";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TTextureStyle::getParamValue(TColorStyle::bool_tag, int index) const {
Shinya Kitaoka 120a6e
  assert(index == 0);
Shinya Kitaoka 120a6e
  return m_params.m_isPattern;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TTextureStyle::getParamValue(TColorStyle::double_tag, int index) const {
Shinya Kitaoka 120a6e
  assert(index > 1);
Shinya Kitaoka 120a6e
  switch (index) {
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    return m_params.m_scale;
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    return m_params.m_rotation;
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    return m_params.m_displacement.x;
Shinya Kitaoka 120a6e
  case 5:
Shinya Kitaoka 120a6e
    return m_params.m_displacement.y;
Shinya Kitaoka 120a6e
  case 6:
Shinya Kitaoka 120a6e
    return m_params.m_contrast;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFilePath TTextureStyle::getParamValue(TColorStyle::TFilePath_tag,
Shinya Kitaoka 120a6e
                                       int index) const {
Shinya Kitaoka 120a6e
  assert(index == 7);
Shinya Kitaoka 120a6e
  return m_texturePath;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TTextureStyle::getParamValue(TColorStyle::int_tag, int index) const {
Shinya Kitaoka 120a6e
  assert(index == 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_params.m_type;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setParamValue(int index, const TFilePath &value) {
Shinya Kitaoka 120a6e
  assert(index == 7);
Shinya Kitaoka 120a6e
  m_texturePath = value;
Shinya Kitaoka 120a6e
  setAverageColor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setParamValue(int index, int value) {
Shinya Kitaoka 120a6e
  assert(index == 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_params.m_type = (TTextureParams::TYPE)value;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setParamValue(int index, bool value) {
Shinya Kitaoka 120a6e
  assert(index == 0);
Shinya Kitaoka 120a6e
  m_params.m_isPattern = value;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setParamValue(int index, double value) {
Shinya Kitaoka 120a6e
  assert(index > 1);
Shinya Kitaoka 120a6e
  switch (index) {
Shinya Kitaoka 120a6e
  case 0:
Shinya Kitaoka 120a6e
    m_params.m_isPattern = (((int)value == 0) ? false : true);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    m_params.m_type =
Shinya Kitaoka 120a6e
        (((int)value == 0) ? TTextureParams::FIXED
Shinya Kitaoka 120a6e
                           : ((int)value == 1) ? TTextureParams::AUTOMATIC
Shinya Kitaoka 120a6e
                                               : TTextureParams::RANDOM);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    m_params.m_scale = value;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    m_params.m_rotation = value;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    m_params.m_displacement.x = value;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 5:
Shinya Kitaoka 120a6e
    m_params.m_displacement.y = value;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 6:
Shinya Kitaoka 120a6e
    m_params.m_contrast = value;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TTextureStyle::loadTextureRaster() {
Shinya Kitaoka 120a6e
  if (m_texturePathLoaded != TFilePath() &&
Shinya Kitaoka 120a6e
      m_texturePath == m_texturePathLoaded)
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_texturePathLoaded = m_texturePath;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath path;
Shinya Kitaoka 120a6e
  if (m_texturePath.getParentDir() != TFilePath())  // It's a custom texture
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    assert(m_currentScene);
Shinya Kitaoka 120a6e
    path = m_currentScene->decodeFilePath(m_texturePath);
Shinya Kitaoka 120a6e
    if (path.isLevelName()) {
Shinya Kitaoka 120a6e
      TLevelReader lr(path);
Shinya Kitaoka 120a6e
      path = path.withFrame(lr.loadInfo()->begin()->first);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else  // is a library texture
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    path = m_texturePath.withParentDir(m_libraryDir + "textures");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP aux;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!TImageReader::load(path, aux)) {
Shinya Kitaoka 120a6e
    m_texture = TRaster32P(128, 128);
Shinya Kitaoka 120a6e
    m_texture->clear();
Shinya Kitaoka 120a6e
    m_texturePathLoaded = TFilePath();
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_texture = aux;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TRaster32P TTextureStyle::loadTextureRasterWithFrame(int frame) const {
Shinya Kitaoka 120a6e
  if (m_texturePathLoaded != TFilePath() &&
Shinya Kitaoka 120a6e
      m_texturePath == m_texturePathLoaded &&
Shinya Kitaoka 120a6e
      (!m_texturePath.isLevelName() || frame == 0))
Shinya Kitaoka 120a6e
    return m_texture->clone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath path;
Shinya Kitaoka 120a6e
  if (m_texturePath.getParentDir() != TFilePath())  // It's a custom texture
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    assert(m_currentScene);
Shinya Kitaoka 120a6e
    path = m_currentScene->decodeFilePath(m_texturePath);
Shinya Kitaoka 120a6e
    if (path.isLevelName()) {
Shinya Kitaoka 120a6e
      TLevelReader lr(path);
Shinya Kitaoka 120a6e
      TLevelP info        = lr.loadInfo();
Shinya Kitaoka 120a6e
      TLevel::Iterator it = info->begin();
Shinya Kitaoka 120a6e
      // frame = frame % (lr.loadInfo()->getFrameCount());
Shinya Kitaoka 120a6e
      std::advance(it, frame % (info->getFrameCount()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      //
Shinya Kitaoka 120a6e
      path = path.withFrame(it->first);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else  // is a library texture
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    path = m_texturePath.withParentDir(m_libraryDir + "textures");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP aux;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!TImageReader::load(path, aux)) {
Shinya Kitaoka 120a6e
    aux = TRaster32P(128, 128);
Shinya Kitaoka 120a6e
    aux->clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return aux;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::loadData(TInputStreamInterface &is) {
Shinya Kitaoka 120a6e
  if (is.versionNumber().first < 71) {
Shinya Kitaoka 120a6e
    is >> m_texture;
Shinya Kitaoka 120a6e
    setTexture(m_texture);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string path;
Shinya Kitaoka 120a6e
  is >> path;
Shinya Kitaoka 120a6e
  m_texturePath = TFilePath(path);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TOutlineStyle::loadData(is);
Shinya Kitaoka 120a6e
  // is >> m_texture;
Shinya Kitaoka 120a6e
  loadTextureRaster();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  is >> m_params.m_patternColor;
Shinya Kitaoka 120a6e
  m_averageColor = m_params.m_patternColor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double value;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  is >> value;
Shinya Kitaoka 120a6e
  m_params.m_isPattern = value == 1.0 ? true : false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  is >> value;
Shinya Kitaoka 120a6e
  m_params.m_type =
Shinya Kitaoka 120a6e
      (((int)value == 0) ? TTextureParams::FIXED
Shinya Kitaoka 120a6e
                         : ((int)value == 1) ? TTextureParams::AUTOMATIC
Shinya Kitaoka 120a6e
                                             : TTextureParams::RANDOM);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  is >> m_params.m_scale;
Shinya Kitaoka 120a6e
  is >> m_params.m_rotation;
Shinya Kitaoka 120a6e
  is >> m_params.m_displacement.x;
Shinya Kitaoka 120a6e
  is >> m_params.m_displacement.y;
Shinya Kitaoka 120a6e
  is >> m_params.m_contrast;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete m_tessellator;
Shinya Kitaoka 120a6e
  m_tessellator = new TglTessellator;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setAverageColor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::saveData(TOutputStreamInterface &os) const {
Shinya Kitaoka 120a6e
  // TOutlineStyle::saveData(os);
Shinya Kitaoka 120a6e
  // os << m_texture;
Shinya Kitaoka 120a6e
  std::wstring wstr = m_texturePath.getWideString();
Shinya Kitaoka 120a6e
  std::string str;
Shinya Kitaoka 120a6e
  str.assign(wstr.begin(), wstr.end());
Shinya Kitaoka 120a6e
  os << str;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << m_params.m_patternColor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << ((double)m_params.m_isPattern);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double value = (m_params.m_type == TTextureParams::FIXED)
Shinya Kitaoka 120a6e
                     ? 0
Shinya Kitaoka 120a6e
                     : ((m_params.m_type == TTextureParams::AUTOMATIC) ? 1 : 2);
Shinya Kitaoka 120a6e
  os << value;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << m_params.m_scale;
Shinya Kitaoka 120a6e
  os << m_params.m_rotation;
Shinya Kitaoka 120a6e
  os << m_params.m_displacement.x;
Shinya Kitaoka 120a6e
  os << m_params.m_displacement.y;
Shinya Kitaoka 120a6e
  os << m_params.m_contrast;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TTextureStyle::getColorParamCount() const { return 1; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPixel32 TTextureStyle::getColorParamValue(int index) const {
Shinya Kitaoka 120a6e
  return m_params.m_patternColor;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::setColorParamValue(int index, const TPixel32 &color) {
Shinya Kitaoka 120a6e
  m_params.m_patternColor = color;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
inline void drawdot(TPixel32 *pix, int wrap) {
Shinya Kitaoka 120a6e
  for (int i = -wrap; i <= wrap; i += wrap)
Shinya Kitaoka 120a6e
    for (int j = -1; j <= 1; j++) *(pix + i + j) = TPixel::Red;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TTextureStyle::fillCustomTextureIcon(const TRaster32P &r) {
Shinya Kitaoka 120a6e
  r->fill(TPixel::White);
Shinya Kitaoka 120a6e
  int x1, x2, x3;
Shinya Kitaoka 120a6e
  x2 = r->getLx() / 2;
Shinya Kitaoka 120a6e
  x1 = x2 + ((r->getLx() <= 64) ? 6 : 9);
Shinya Kitaoka 120a6e
  x3 = x2 - ((r->getLx() <= 64) ? 6 : 9);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPixel32 *pix = r->pixels(r->getLy() / 4);
Shinya Kitaoka 120a6e
  drawdot(pix + x1, r->getWrap());
Shinya Kitaoka 120a6e
  drawdot(pix + x2, r->getWrap());
Shinya Kitaoka 120a6e
  drawdot(pix + x3, r->getWrap());
Shinya Kitaoka 120a6e
  // TImageWriter::save(TFilePath("C:\\temp\\boh.png"), r);
Shinya Kitaoka 120a6e
  /**(pix+x1) = TPixel::Black;
Toshihiro Shimizu 890ddd
*(pix+x2) = TPixel::Black;
Toshihiro Shimizu 890ddd
*(pix+x3) = TPixel::Black;*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTextureStyle::makeIcon(const TDimension &outputRect) {
Shinya Kitaoka 120a6e
  if (!m_icon || m_icon->getSize() != outputRect) {
Shinya Kitaoka 120a6e
    TRaster32P ras(outputRect);
Shinya Kitaoka 120a6e
    ras->fill(TPixel::Red);
Shinya Kitaoka 120a6e
    m_icon = ras;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!loadTextureRaster()) {
Shinya Kitaoka 120a6e
    fillCustomTextureIcon(m_icon);
Shinya Kitaoka 120a6e
    // m_icon->fill(TPixel::Green);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TRaster32P rTex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_params.m_contrast != 1.0 || m_params.m_isPattern) {
Shinya Kitaoka 120a6e
    rTex = m_texture->clone();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_params.m_contrast != 1.0) doContrast(m_params.m_contrast, rTex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_params.m_isPattern) doPattern(rTex, m_params.m_patternColor);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    rTex = m_texture;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double fitScale = std::min((double)(outputRect.lx) / m_texture->getLx(),
Shinya Kitaoka 120a6e
                             (double)(outputRect.ly) / m_texture->getLy());
Shinya Kitaoka 120a6e
  TAffine affine =
Shinya Kitaoka 120a6e
      TScale(m_params.m_scale * (fitScale)) * TRotation(-m_params.m_rotation);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (affine != TAffine()) {
Shinya Kitaoka 120a6e
    int border = 2;
Shinya Kitaoka 120a6e
    TRaster32P raux(m_icon->getLx() + 2 * border, m_icon->getLy() + 2 * border);
Shinya Kitaoka 120a6e
    TRaster32P rin(convert(affine.inv() *
Shinya Kitaoka 120a6e
                           TRectD(0, 0, raux->getLx() - 1, raux->getLy() - 1))
Shinya Kitaoka 120a6e
                       .getSize());
Shinya Kitaoka 120a6e
    tileRaster(rTex, rin);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRop::resample(raux, rin,
Shinya Kitaoka 120a6e
                   affine.place(rin->getCenterD(), raux->getCenterD()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRop::copy(m_icon,
Shinya Kitaoka 120a6e
               raux->extract(border, border, m_icon->getLx() + border - 1,
Shinya Kitaoka 120a6e
                             m_icon->getLy() + border - 1));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    applyTexture(rTex, m_icon, TPoint());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TTextureStyle::doCompute(const Params ¶ms) const {
Shinya Kitaoka 120a6e
  TRaster32P rTex = loadTextureRasterWithFrame(params.m_frame);
Shinya Kitaoka 120a6e
  TRaster32P r    = params.m_r;
Shinya Kitaoka 120a6e
  // TRaster32P rTex = m_texture->clone();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(r);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_params.m_contrast != 1.0) doContrast(m_params.m_contrast, rTex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_params.m_isPattern) doPattern(rTex, m_params.m_patternColor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPoint p = -convert(m_params.m_displacement);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_params.m_type == TTextureParams::FIXED)
Shinya Kitaoka 120a6e
    p += params.m_p;
Shinya Kitaoka 120a6e
  else if (m_params.m_type == TTextureParams::RANDOM)
Shinya Kitaoka 120a6e
    p += TPoint(Random.getUInt(m_texture->getLx()),
Shinya Kitaoka 120a6e
                Random.getUInt(m_texture->getLy()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_params.m_scale != 1.0 || m_params.m_rotation != 0.0) {
Shinya Kitaoka 120a6e
    TAffine affine = TScale(m_params.m_scale) * TRotation(-m_params.m_rotation);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_params.m_type == TTextureParams::AUTOMATIC) {
Shinya Kitaoka 120a6e
      TRect bBox;
Shinya Kitaoka 120a6e
      TRop::computeBBox(r, bBox);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      r = r->extract(bBox);
Shinya Kitaoka 120a6e
      p += r->getCenter() - computeCentroid(r);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    p.x = (p.x % m_texture->getLx());
Shinya Kitaoka 120a6e
    p.y = (p.y % m_texture->getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRect rectIn =
Shinya Kitaoka 120a6e
        convert(affine.inv() * TRectD(0, 0, r->getLx() - 1, r->getLy() - 1));
Shinya Kitaoka 120a6e
    TRaster32P rin(rectIn.getLx() + abs(p.x), rectIn.getLy() + abs(p.y));
Shinya Kitaoka 120a6e
    TRaster32P rout(r->getSize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    tileRaster(rTex, rin);
Shinya Kitaoka 120a6e
    TRop::resample(rout, rin, affine.place(rin->getCenterD(),
Shinya Kitaoka 120a6e
                                           rout->getCenterD() - convert(p)));
Shinya Kitaoka 120a6e
    rTex = rout;
Shinya Kitaoka 120a6e
    p    = TPoint();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (m_params.m_type == TTextureParams::AUTOMATIC)
Shinya Kitaoka 120a6e
      p += rTex->getCenter() - computeCentroid(r);
Shinya Kitaoka 120a6e
    p.x = (p.x % m_texture->getLx());
Shinya Kitaoka 120a6e
    p.y = (p.y % m_texture->getLy());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  applyTexture(rTex, r, p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P makeSimpleRaster() {
Shinya Kitaoka 120a6e
  TRaster32P ras(2, 2);
Shinya Kitaoka 120a6e
  ras->fill(TPixel32::White);
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TColorStyle::Declaration s2(new TTextureStyle(makeSimpleRaster(), TFilePath()));
Toshihiro Shimizu 890ddd
}