void TMyPaintBrushStyle::makeIcon(const TDimension &d) {
  TFilePath path = m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
  if (!m_preview) {
    m_icon = TRaster32P(d);
    m_icon->fill(TPixel32::Red);
  } else
  if (m_preview->getSize() == d) {
    m_icon = m_preview;
  } else {
    m_icon = TRaster32P(d);
    double sx = (double)d.lx/(double)m_preview->getLx();
    double sy = (double)d.ly/(double)m_preview->getLy();
    TRop::resample(m_icon, m_preview, TScale(sx, sy));
  }

  // paint color marker
  if (d.lx > 0 && d.ly > 0) {
    int size = std::min( 1 + std::min(d.lx, d.ly)*2/3,
                         1 + std::max(d.lx, d.ly)/2 );
    TPixel32 color = getMainColor();
    for(int y = 0; y < size; ++y) {
      TPixel32 *p = m_icon->pixels(d.ly - y - 1);
      TPixel32 *endp = p + size - y - 1;
      for( ;p != endp; ++p)
        *p = color;
      *p = blend(*p, color, 0.5);
    }
  }
}
Esempio n. 2
0
void tglBuildMipmaps(std::vector<TRaster32P> &rasters,
					 const TFilePath &filepath)
{
	assert(rasters.size() > 0);
	TRop::ResampleFilterType resampleFilter = TRop::ClosestPixel;
	TRasterP ras;
	TImageReader::load(filepath, ras);
	int rasLx = ras->getLx();
	int rasLy = ras->getLy();

	int lx = 1;
	while (lx < rasLx)
		lx <<= 1;

	int ly = 1;
	while (ly < rasLy)
		ly <<= 1;

	TRaster32P ras2(lx, ly);
	double sx = (double)lx / (double)ras->getLx();
	double sy = (double)ly / (double)ras->getLy();
#ifndef SCALE_BY_GLU
	TRop::resample(ras2, ras, TScale(sx, sy), resampleFilter);
#else
	ras->lock();
	gluScaleImage(GL_RGBA, ras->getLx(), ras->getLy(), GL_UNSIGNED_BYTE, ras->getRawData(),
				  lx, ly, GL_UNSIGNED_BYTE, ras2->getRawData());
	ras->unlock();
#endif

	rasters[0] = ras2;
	int ras2Lx = ras2->getLx();
	int ras2Ly = ras2->getLy();
	for (int i = 1; i < (int)rasters.size(); ++i) {
		lx >>= 1;
		ly >>= 1;
		if (lx < 1)
			lx = 1;
		if (ly < 1)
			ly = 1;
		rasters[i] = TRaster32P(lx, ly);
		sx = (double)lx / (double)ras2Lx;
		sy = (double)ly / (double)ras2Ly;
		rasters[i] = TRaster32P(lx, ly);
#ifndef SCALE_BY_GLU
		TRop::resample(rasters[i], ras2, TScale(sx, sy), resampleFilter);
#else
		ras2->lock();
		gluScaleImage(GL_RGBA, ras->getLx(), ras->getLy(), GL_UNSIGNED_BYTE, ras2->getRawData(),
					  lx, ly, GL_UNSIGNED_BYTE, rasters[i]->getRawData());
		ras2->unlock();
#endif
	}
}
Esempio n. 3
0
TRasterP TRop::shrink(TRasterP rin, int shrink) {
  int pixelSize = rin->getPixelSize();

  int lx = (rin->getLx() - 1) / shrink + 1;
  int ly = (rin->getLy() - 1) / shrink + 1;

  TRasterP rout;

  if ((TRaster32P)rin)
    rout = TRaster32P(lx, ly);
  else if ((TRaster64P)rin)
    rout                      = TRaster64P(lx, ly);
  if ((TRasterCM32P)rin) rout = TRasterCM32P(lx, ly);
  if ((TRasterGR8P)rin) rout  = TRasterGR8P(lx, ly);

  int i, j;

  for (i = 0; i < ly; i++) {
    UCHAR *bufin =
        (UCHAR *)rin->getRawData() + (i * shrink) * rin->getWrap() * pixelSize;
    UCHAR *bufout =
        (UCHAR *)rout->getRawData() + i * rout->getWrap() * pixelSize;
    for (j = 0; j < lx; j++) {
      memcpy(bufout, bufin, pixelSize);
      bufin += shrink * pixelSize;
      bufout += pixelSize;
    }
  }
  return rout;
}
Esempio n. 4
0
inline TRasterP TCacheResource::createCellRaster(int rasterType, const std::string &cacheId)
{
	TRasterP result;

	if (rasterType == TCacheResource::NONE) {
		assert(!"Unknown raster type!");
		return result;
	}

	TImageP img;
	if (rasterType == TCacheResource::RGBM32) {
		result = TRaster32P(latticeStep, latticeStep);
		img = TRasterImageP(result);
	} else if (rasterType == TCacheResource::RGBM64) {
		result = TRaster64P(latticeStep, latticeStep);
		img = TRasterImageP(result);
	} else if (rasterType == TCacheResource::CM32) {
		result = TRasterCM32P(latticeStep, latticeStep);
		img = TToonzImageP(result, result->getBounds());
	}

	TImageCache::instance()->add(cacheId, img);
	++m_cellsCount;

	//DIAGNOSTICS_GLOADD("crCellsCnt", 1);

	return result;
}
Esempio n. 5
0
TRaster32P PlaneViewer::rasterBuffer() {
  if (!m_rasterBuffer || m_rasterBuffer->getLx() != width() ||
      m_rasterBuffer->getLy() != height())
    m_rasterBuffer = TRaster32P(width(), height());

  return m_rasterBuffer;
}
Esempio n. 6
0
TRasterP TCacheResource::buildCompatibleRaster(const TDimension &size)
{
	TRasterP result;
	if (m_tileType == RGBM32)
		result = TRaster32P(size);
	else if (m_tileType == RGBM64)
		result = TRaster64P(size);
	else if (m_tileType == CM32)
		result = TRasterCM32P(size);

	return result;
}
Esempio n. 7
0
void ColumnColorFilterFx::doCompute(TTile &tile, double frame,
                                    const TRenderSettings &ri) {
  if (!m_port.isConnected()) return;

  if (!TRaster32P(tile.getRaster()) && !TRaster64P(tile.getRaster()))
    throw TException("AffineFx unsupported pixel type");

  TRasterFxP src = m_port.getFx();
  src->compute(tile, frame, ri);

  TRop::applyColorScale(tile.getRaster(), m_colorFilter);
}
void FullColorBrushTool::setWorkAndBackupImages()
{
	TRasterImageP ri = (TRasterImageP)getImage(false, 1);
	if (!ri)
		return;

	TRasterP ras = ri->getRaster();
	TDimension dim = ras->getSize();

	if (!m_workRaster || m_workRaster->getLx() > dim.lx || m_workRaster->getLy() > dim.ly)
		m_workRaster = TRaster32P(dim);

	if (!m_backUpRas || m_backUpRas->getLx() > dim.lx || m_backUpRas->getLy() > dim.ly ||
		m_backUpRas->getPixelSize() != ras->getPixelSize())
		m_backUpRas = ras->create(dim.lx, dim.ly);

	m_strokeRect.empty();
	m_lastRect.empty();
}
Esempio n. 9
0
void convertForWriting(TRasterP &ras, const TRasterP &rin, int bpp)
{
	switch (bpp) {
	case 1:
	case 8:
		ras = TRasterGR8P(rin->getSize());
		TRop::convert(ras, rin);
		break;
	case 24:
	case 32:
		ras = TRaster32P(rin->getSize());
		TRop::convert(ras, rin);
		break;
	case 48:
	case 64:
		ras = TRaster64P(rin->getSize());
		TRop::convert(ras, rin);
		break;
	default:
		assert(false);
	}
}
Esempio n. 10
0
//------------------------------------------------------------------------------
void CleanupSwatch::CleanupSwatchArea::updateRaster(bool dragging)
{
	if (isHidden() || m_sw->m_lx == 0 || m_sw->m_ly == 0)
		return;

	if (!m_r || m_r->getLx() != m_sw->m_lx || m_r->getLy() != m_sw->m_ly)
		m_r = TRaster32P(m_sw->m_lx, m_sw->m_ly);

	if (!m_sw->m_resampledRaster)
		m_r->fill(TPixel(200, 200, 200));
	else {
		m_r->fill(TPixel::White);
		if (m_isLeft)
			TRop::quickPut(m_r, m_sw->m_origRaster, getFinalAff() * m_sw->m_resampleAff);
		else
			updateCleanupped(dragging);
	}
	if (dragging)
		repaint();
	else
		update();
}
QScriptValue ImageBuilder::ctor(QScriptContext *context,
                                QScriptEngine *engine) {
  ImageBuilder *imageBuilder = 0;
  if (context->argumentCount() == 2 || context->argumentCount() == 3) {
    if (!context->argument(0).isNumber() || !context->argument(1).isNumber())
      return context->throwError("Bad arguments: expected width,height[,type]");
    int width  = (int)(context->argument(0).toNumber());
    int height = (int)(context->argument(1).toNumber());
    if (width <= 0 || height <= 0) return context->throwError("Bad size");
    QString type;
    if (context->argumentCount() == 3) {
      if (context->argument(2).isString())
        type = context->argument(2).toString();
      if (type != "Raster" && type != "ToonzRaster")
        return context->throwError(
            tr("Bad argument (%1): should be 'Raster' or ToonzRaster'")
                .arg(context->argument(2).toString()));
    }
    imageBuilder           = new ImageBuilder();
    imageBuilder->m_width  = width;
    imageBuilder->m_height = height;
    if (type == "Raster")
      imageBuilder->m_img = new TRasterImage(TRaster32P(width, height));
    else if (type == "ToonzRaster") {
      imageBuilder->m_img = new TToonzImage(TRasterCM32P(width, height),
                                            TRect(0, 0, width, height));
    }
  } else {
    if (context->argumentCount() != 0)
      return context->throwError(
          "Bad argument count. expected: width,height[,type]");
    imageBuilder = new ImageBuilder();
  }
  QScriptValue obj =
      engine->newQObject(imageBuilder, QScriptEngine::AutoOwnership,
                         QScriptEngine::ExcludeSuperClassContents |
                             QScriptEngine::ExcludeSuperClassMethods);
  return obj;
}
Esempio n. 12
0
void TGeometryFx::doCompute(TTile &tile, double frame,
                            const TRenderSettings &ri) {
  TRasterFxPort *input = dynamic_cast<TRasterFxPort *>(getInputPort(0));
  assert(input);

  if (!input->isConnected()) return;

  if (!getActiveTimeRegion().contains(frame)) {
    TRasterFxP(input->getFx())->compute(tile, frame, ri);
    return;
  }

  if (!TRaster32P(tile.getRaster()) && !TRaster64P(tile.getRaster()))
    throw TException("AffineFx unsupported pixel type");

  TAffine aff1 = getPlacement(frame);
  TRenderSettings ri2(ri);
  ri2.m_affine = ri2.m_affine * aff1;

  TRasterFxP src = getInputPort("source")->getFx();
  src->compute(tile, frame, ri2);
  return;
}
void FullColorBrushTool::onDeactivate()
{
	m_workRaster = TRaster32P();
	m_backUpRas = TRasterP();
}
Esempio n. 14
0
void blend(TToonzImageP ti, TRasterPT<PIXEL> rasOut,
           const std::vector<BlendParam> &params) {
  assert(ti->getRaster()->getSize() == rasOut->getSize());

  // Extract the interesting raster. It should be the savebox of passed cmap,
  // plus - if
  // some param has the 0 index as blending color - the intensity of that blend
  // param.
  unsigned int i, j;
  TRect saveBox(ti->getSavebox());

  int enlargement = 0;
  for (i = 0; i < params.size(); ++i)
    for (j = 0; j < params[i].colorsIndexes.size(); ++j)
      if (params[i].colorsIndexes[j] == 0)
        enlargement = std::max(enlargement, tceil(params[i].intensity));
  saveBox           = saveBox.enlarge(enlargement);

  TRasterCM32P cmIn(ti->getRaster()->extract(saveBox));
  TRasterPT<PIXEL> rasOutExtract = rasOut->extract(saveBox);

  // Ensure that cmIn and rasOut have the same size
  unsigned int lx = cmIn->getLx(), ly = cmIn->getLy();

  // Build the pure colors infos
  SelectionRaster selectionRaster(cmIn);

  // Now, build a little group of BlurPatterns - and for each, one for passed
  // param.
  // A small number of patterns per param is needed to make the pattern look not
  // ever the same.
  const int blurPatternsPerParam = 10;
  std::vector<BlurPatternContainer> blurGroup(params.size());

  for (i = 0; i < params.size(); ++i) {
    BlurPatternContainer &blurContainer = blurGroup[i];
    blurContainer.reserve(blurPatternsPerParam);

    for (j = 0; j < blurPatternsPerParam; ++j)
      blurContainer.push_back(BlurPattern(
          params[i].intensity, params[i].smoothness, params[i].stopAtCountour));
  }

  // Build the palette
  TPalette *palette = ti->getPalette();
  std::vector<TPixel32> paletteColors;
  paletteColors.resize(palette->getStyleCount());
  for (i             = 0; i < paletteColors.size(); ++i)
    paletteColors[i] = premultiply(palette->getStyle(i)->getAverageColor());

  // Build the 4 auxiliary rasters for the blending procedure: they are ink /
  // paint versus input / output in the blend.
  // The output raster is reused to spare some memory - it should be, say, the
  // inkLayer's second at the end of the overall
  // blending procedure. It could be the first, without the necessity of
  // clearing it before blending the layers, but things
  // get more complicated when PIXEL is TPixel64...
  RGBMRasterPair inkLayer, paintLayer;

  TRaster32P rasOut32P_1(lx, ly, lx, (TPixel32 *)rasOut->getRawData(), false);
  inkLayer.first  = (params.size() % 2) ? rasOut32P_1 : TRaster32P(lx, ly);
  inkLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_1;

  if (PIXEL::maxChannelValue >= TPixel64::maxChannelValue) {
    TRaster32P rasOut32P_2(lx, ly, lx,
                           ((TPixel32 *)rasOut->getRawData()) + lx * ly, false);
    paintLayer.first  = (params.size() % 2) ? rasOut32P_2 : TRaster32P(lx, ly);
    paintLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_2;
  } else {
    paintLayer.first  = TRaster32P(lx, ly);
    paintLayer.second = TRaster32P(lx, ly);
  }

  inkLayer.first->clear();
  inkLayer.second->clear();
  paintLayer.first->clear();
  paintLayer.second->clear();

  // Now, we have to perform the blur of each of the cm's pixels.
  cmIn->lock();
  rasOut->lock();

  inkLayer.first->lock();
  inkLayer.second->lock();
  paintLayer.first->lock();
  paintLayer.second->lock();

  // Convert the initial cmIn to fullcolor ink - paint layers
  buildLayers(cmIn, paletteColors, inkLayer.first, paintLayer.first);

  // Perform the blend on separated ink - paint layers
  for (i = 0; i < params.size(); ++i) {
    if (params[i].colorsIndexes.size() == 0) continue;

    selectionRaster.updateSelection(cmIn, params[i]);
    doBlend(cmIn, inkLayer, paintLayer, selectionRaster, blurGroup[i]);

    tswap(inkLayer.first, inkLayer.second);
    tswap(paintLayer.first, paintLayer.second);
  }

  // Release the unnecessary rasters
  inkLayer.second->unlock();
  paintLayer.second->unlock();
  inkLayer.second   = TRaster32P();
  paintLayer.second = TRaster32P();

  // Clear rasOut - since it was reused to spare space...
  rasOut->clear();

  // Add the ink & paint layers on the output raster
  double PIXELmaxChannelValue = PIXEL::maxChannelValue;
  double toPIXELFactor =
      PIXELmaxChannelValue / (double)TPixel32::maxChannelValue;
  double inkFactor, paintFactor;
  TPoint pos;

  PIXEL *outPix, *outBegin    = (PIXEL *)rasOutExtract->getRawData();
  TPixelCM32 *cmPix, *cmBegin = (TPixelCM32 *)cmIn->getRawData();
  int wrap = rasOutExtract->getWrap();

  TPixel32 *inkPix   = (TPixel32 *)inkLayer.first->getRawData();
  TPixel32 *paintPix = (TPixel32 *)paintLayer.first->getRawData();

  for (i = 0; i < ly; ++i) {
    outPix = outBegin + wrap * i;
    cmPix  = cmBegin + wrap * i;
    for (j = 0; j < lx; ++j, ++outPix, ++cmPix, ++inkPix, ++paintPix) {
      getFactors(cmPix->getTone(), inkFactor, paintFactor);

      outPix->r = tcrop(
          toPIXELFactor * (inkFactor * inkPix->r + paintFactor * paintPix->r),
          0.0, PIXELmaxChannelValue);
      outPix->g = tcrop(
          toPIXELFactor * (inkFactor * inkPix->g + paintFactor * paintPix->g),
          0.0, PIXELmaxChannelValue);
      outPix->b = tcrop(
          toPIXELFactor * (inkFactor * inkPix->b + paintFactor * paintPix->b),
          0.0, PIXELmaxChannelValue);
      outPix->m = tcrop(
          toPIXELFactor * (inkFactor * inkPix->m + paintFactor * paintPix->m),
          0.0, PIXELmaxChannelValue);
    }
  }

  inkLayer.first->unlock();
  paintLayer.first->unlock();

  cmIn->unlock();
  rasOut->unlock();

  // Destroy the auxiliary bitmaps
  selectionRaster.destroy();
}
/*- render_particles から呼ばれる。粒子の数だけ繰り返し -*/
void Particles_Engine::do_render(
    TFlash *flash, Particle *part, TTile *tile,
    std::vector<TRasterFxPort *> part_ports, std::map<int, TTile *> porttiles,
    const TRenderSettings &ri, TDimension &p_size, TPointD &p_offset,
    int lastframe, std::vector<TLevelP> partLevel,
    struct particles_values &values, double opacity_range, int dist_frame,
    std::map<std::pair<int, int>, double> &partScales) {
  // Retrieve the particle frame - that is, the *column frame* from which we are
  // picking
  // the particle to be rendered.
  int ndx = part->frame % lastframe;

  TRasterP tileRas(tile->getRaster());

  std::string levelid;
  double aim_angle = 0;
  if (values.pathaim_val) {
    double arctan = atan2(part->vy, part->vx);
    aim_angle     = arctan * M_180_PI;
  }

  // Calculate the rotational and scale components we have to apply on the
  // particle
  TRotation rotM(part->angle + aim_angle);
  TScale scaleM(part->scale);
  TAffine M(rotM * scaleM);

  // Particles deal with dpi affines on their own
  TAffine scaleAff(m_parent->handledAffine(ri, m_frame));
  double partScale =
      scaleAff.a11 * partScales[std::pair<int, int>(part->level, ndx)];
  TDimensionD partResolution(0, 0);
  TRenderSettings riNew(ri);

  // Retrieve the bounding box in the standard reference
  TRectD bbox(-5.0, -5.0, 5.0, 5.0), standardRefBBox;
  if (part->level <
          (int)part_ports.size() &&  // Not the default levelless cases
      part_ports[part->level]->isConnected()) {
    TRenderSettings riIdentity(ri);
    riIdentity.m_affine = TAffine();

    (*part_ports[part->level])->getBBox(ndx, bbox, riIdentity);

    // A particle's bbox MUST be finite. Gradients and such which have an
    // infinite bbox
    // are just NOT rendered.

    // NOTE: No fx returns half-planes or similar (ie if any coordinate is
    // either
    // (std::numeric_limits<double>::max)() or its opposite, then the rect IS
    // THE infiniteRectD)
    if (bbox == TConsts::infiniteRectD) return;
  }

  // Now, these are the particle rendering specifications
  bbox            = bbox.enlarge(3);
  standardRefBBox = bbox;
  riNew.m_affine  = TScale(partScale);
  bbox            = riNew.m_affine * bbox;
  /*- 縮小済みのParticleのサイズ -*/
  partResolution = TDimensionD(tceil(bbox.getLx()), tceil(bbox.getLy()));

  if (flash) {
    if (!partLevel[part->level]->frame(ndx)) {
      if (part_ports[0]->isConnected()) {
        TTile auxTile;
        TRaster32P tmp;
        tmp = TRaster32P(p_size);
        (*part_ports[0])
            ->allocateAndCompute(auxTile, p_offset, p_size, tmp, ndx, ri);
        partLevel[part->level]->setFrame(ndx,
                                         TRasterImageP(auxTile.getRaster()));
      }
    }

    flash->pushMatrix();

    const TAffine aff;

    flash->multMatrix(scaleM * aff.place(0, 0, part->x, part->y));

    // if(curr_opacity!=1.0 || part->gencol.fadecol || part->fincol.fadecol ||
    // part->foutcol.fadecol)
    {
      TColorFader cf(TPixel32::Red, .5);
      flash->draw(partLevel[part->level]->frame(ndx), &cf);
    }
    // flash->draw(partLevel->frame(ndx), 0);

    flash->popMatrix();
  } else {
    TRasterP ras;

    std::string alias;
    TRasterImageP rimg;
    if (rimg = partLevel[part->level]->frame(ndx)) {
      ras = rimg->getRaster();
    } else {
      alias = "PART: " + (*part_ports[part->level])->getAlias(ndx, riNew);
      if (rimg = TImageCache::instance()->get(alias, false)) {
        ras = rimg->getRaster();

        // Check that the raster resolution is sufficient for our purposes
        if (ras->getLx() < partResolution.lx ||
            ras->getLy() < partResolution.ly)
          ras = 0;
        else
          partResolution = TDimensionD(ras->getLx(), ras->getLy());
      }
    }

    // We are interested in making the relation between scale and (integer)
    // resolution
    // bijective - since we shall cache by using resolution as a partial
    // identification parameter.
    // Therefore, we find the current bbox Lx and take a unique scale out of it.
    partScale      = partResolution.lx / standardRefBBox.getLx();
    riNew.m_affine = TScale(partScale);
    bbox           = riNew.m_affine * standardRefBBox;

    // If no image was retrieved from the cache (or it was not scaled enough),
    // calculate it
    if (!ras) {
      TTile auxTile;
      (*part_ports[part->level])
          ->allocateAndCompute(auxTile, bbox.getP00(),
                               TDimension(partResolution.lx, partResolution.ly),
                               tile->getRaster(), ndx, riNew);
      ras = auxTile.getRaster();

      // For now, we'll just use 32 bit particles
      TRaster32P rcachepart;
      rcachepart = ras;
      if (!rcachepart) {
        rcachepart = TRaster32P(ras->getSize());
        TRop::convert(rcachepart, ras);
      }
      ras = rcachepart;

      // Finally, cache the particle
      addRenderCache(alias, TRasterImageP(ras));
    }

    if (!ras) return;  // At this point, it should never happen anyway...

    // Deal with particle colors/opacity
    TRaster32P rfinalpart;
    double curr_opacity =
        part->set_Opacity(porttiles, values, opacity_range, dist_frame);
    if (curr_opacity != 1.0 || part->gencol.fadecol || part->fincol.fadecol ||
        part->foutcol.fadecol) {
      /*- 毎フレーム現在位置のピクセル色を参照 -*/
      if (values.pick_color_for_every_frame_val && values.gencol_ctrl_val &&
          (porttiles.find(values.gencol_ctrl_val) != porttiles.end()))
        part->get_image_reference(porttiles[values.gencol_ctrl_val], values,
                                  part->gencol.col);

      rfinalpart = ras->clone();
      part->modify_colors_and_opacity(values, curr_opacity, dist_frame,
                                      rfinalpart);
    } else
      rfinalpart = ras;

    // Now, let's build the particle transform before it is overed on the output
    // tile

    // First, complete the transform by adding the rotational and scale
    // components from
    // Particles parameters
    M = ri.m_affine * M * TScale(1.0 / partScale);

    // Then, retrieve the particle position in current reference.
    TPointD pos(part->x, part->y);
    pos = ri.m_affine * pos;

    // Finally, add the translational component to the particle
    // NOTE: p_offset is added to account for the particle relative position
    // inside its level's bbox
    M = TTranslation(pos - tile->m_pos) * M * TTranslation(bbox.getP00());

    if (TRaster32P myras32 = tile->getRaster())
      TRop::over(tileRas, rfinalpart, M);
    else if (TRaster64P myras64 = tile->getRaster())
      TRop::over(tileRas, rfinalpart, M);
    else
      throw TException("ParticlesFx: unsupported Pixel Type");
  }
}
Esempio n. 16
0
//! Disposes of the auxiliary internal rasterBuffer().
void PlaneViewer::hideEvent(QHideEvent *event) {
  m_rasterBuffer = TRaster32P();
}
Esempio n. 17
0
void subCompute(TRasterFxPort &m_input, TTile &tile, double frame,
                const TRenderSettings &ri, TPointD p00, TPointD p01,
                TPointD p11, TPointD p10, int details, bool wireframe,
                TDimension m_offScreenSize, bool isCast) {
  TPixel32 bgColor;
  TRectD outBBox, inBBox;
  outBBox = inBBox = TRectD(tile.m_pos, TDimensionD(tile.getRaster()->getLx(),
                                                    tile.getRaster()->getLy()));
  m_input->getBBox(frame, inBBox, ri);
  if (inBBox == TConsts::infiniteRectD)  // e' uno zerario
    inBBox = outBBox;

  int inBBoxLx = (int)inBBox.getLx() / ri.m_shrinkX;
  int inBBoxLy = (int)inBBox.getLy() / ri.m_shrinkY;

  if (inBBox.isEmpty()) return;

  if (p00 == p01 && p00 == p10 && p00 == p11 &&
      !isCast)  // significa che non c'e' deformazione
  {
    m_input->compute(tile, frame, ri);
    return;
  }

  TRaster32P rasIn;
  TPointD rasInPos;

  if (!wireframe) {
    if (ri.m_bpp == 64 || ri.m_bpp == 48) {
      TRaster64P aux = TRaster64P(inBBoxLx, inBBoxLy);
      rasInPos = TPointD(inBBox.x0 / ri.m_shrinkX, inBBox.y0 / ri.m_shrinkY);
      TTile tmp(aux, rasInPos);
      m_input->compute(tmp, frame, ri);
      rasIn = TRaster32P(inBBoxLx, inBBoxLy);
      TRop::convert(rasIn, aux);
    } else {
      rasInPos = TPointD(inBBox.x0 / ri.m_shrinkX, inBBox.y0 / ri.m_shrinkY);
      TTile tmp(TRaster32P(inBBoxLx, inBBoxLy), rasInPos);
      m_input->allocateAndCompute(tmp, rasInPos, TDimension(inBBoxLx, inBBoxLy),
                                  TRaster32P(), frame, ri);
      rasIn = tmp.getRaster();
    }
  }

  unsigned int texWidth  = 2;
  unsigned int texHeight = 2;

  while (texWidth < (unsigned int)inBBoxLx) texWidth = texWidth << 1;

  while (texHeight < (unsigned int)inBBoxLy) texHeight = texHeight << 1;

  while (texWidth > 1024 || texHeight > 1024)  // avevo usato la costante
                                               // GL_MAX_TEXTURE_SIZE invece di
                                               // 1024, ma non funzionava!
  {
    inBBoxLx  = inBBoxLx >> 1;
    inBBoxLy  = inBBoxLy >> 1;
    texWidth  = texWidth >> 1;
    texHeight = texHeight >> 1;
  }

  if (rasIn->getLx() != inBBoxLx || rasIn->getLy() != inBBoxLy) {
    TRaster32P rasOut = TRaster32P(inBBoxLx, inBBoxLy);
    TRop::resample(rasOut, rasIn,
                   TScale((double)rasOut->getLx() / rasIn->getLx(),
                          (double)rasOut->getLy() / rasIn->getLy()));
    rasIn = rasOut;
  }

  int rasterWidth  = tile.getRaster()->getLx() + 2;
  int rasterHeight = tile.getRaster()->getLy() + 2;
  assert(rasterWidth > 0);
  assert(rasterHeight > 0);

  TRectD clippingRect =
      TRectD(tile.m_pos,
             TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy()));
#if CREATE_GL_CONTEXT_ONE_TIME
  int ret = wglMakeCurrent(m_offScreenGL.m_offDC, m_offScreenGL.m_hglRC);
  assert(ret == TRUE);
#else
  TOfflineGL offScreenRendering(TDimension(rasterWidth, rasterHeight));
  //#ifdef _WIN32
  offScreenRendering.makeCurrent();
//#else
//#if defined(LINUX) || defined(MACOSX)
// offScreenRendering.m_offlineGL->makeCurrent();
//#endif
#endif

  checkErrorsByGL
      // disabilito quello che non mi serve per le texture
      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  glDisable(GL_DITHER);
  glDisable(GL_DEPTH_TEST);
  glCullFace(GL_FRONT);
  glDisable(GL_STENCIL_TEST);
  glDisable(GL_LOGIC_OP);

  // creo la texture in base all'immagine originale
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  checkErrorsByGL
#if !CREATE_GL_CONTEXT_ONE_TIME
      TRaster32P rasaux;
  if (!wireframe) {
    TRaster32P texture(texWidth, texHeight);
    texture->clear();
    rasaux = texture;
    rasaux->lock();
    texture->copy(rasIn);

    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glTexImage2D(GL_TEXTURE_2D, 0, 4, texWidth, texHeight, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, texture->getRawData());
  }
#else

      unsigned int texWidth = 1024;
  unsigned int texHeight    = 1024;
  rasaux                    = rasIn;
  rasaux->lock();

  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasIn->getLx(), rasIn->getLy(),
                  GL_RGBA, GL_UNSIGNED_BYTE, rasIn->getRawData());

#endif
  checkErrorsByGL

      glEnable(GL_TEXTURE_2D);

  // cfr. help: OpenGL/Programming tip/OpenGL Correctness Tips
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-rasterWidth * 0.5, rasterWidth * 0.5, -rasterHeight * 0.5,
          rasterHeight * 0.5, -1, 1);
  glViewport(0, 0, rasterWidth, rasterHeight);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT);

  // do OpenGL draw

  double lwTex = (double)(inBBoxLx - 1) / (double)(texWidth - 1);
  double lhTex = (double)(inBBoxLy - 1) / (double)(texHeight - 1);

  TPointD tex00 = TPointD(0.0, 0.0);
  TPointD tex10 = TPointD(lwTex, 0.0);
  TPointD tex11 = TPointD(lwTex, lhTex);
  TPointD tex01 = TPointD(0.0, lhTex);

  GLenum polygonStyle;
  if (wireframe) {
    polygonStyle = GL_LINE;
    glDisable(GL_TEXTURE_2D);
  } else
    polygonStyle = GL_FILL;
  checkErrorsByGL p00.x /= ri.m_shrinkX;
  p00.y /= ri.m_shrinkY;

  p10.x /= ri.m_shrinkX;
  p10.y /= ri.m_shrinkY;

  p11.x /= ri.m_shrinkX;
  p11.y /= ri.m_shrinkY;

  p01.x /= ri.m_shrinkX;
  p01.y /= ri.m_shrinkY;

  TPointD translate = TPointD(tile.m_pos.x + tile.getRaster()->getLx() * 0.5,
                              tile.m_pos.y + tile.getRaster()->getLy() * 0.5);
  glTranslated(-translate.x, -translate.y, 0.0);

  // disegno il poligono
  double dist_p00_p01                 = tdistance2(p00, p01);
  double dist_p10_p11                 = tdistance2(p10, p11);
  double dist_p01_p11                 = tdistance2(p01, p11);
  double dist_p00_p10                 = tdistance2(p00, p10);
  bool vertical                       = (dist_p00_p01 == dist_p10_p11);
  bool horizontal                     = (dist_p00_p10 == dist_p01_p11);
  if (vertical && horizontal) details = 1;
  glPolygonMode(GL_FRONT_AND_BACK, polygonStyle);
  subdivision(p00, p10, p11, p01, tex00, tex10, tex11, tex01, clippingRect,
              details);

  if (!wireframe) {
    // abilito l'antialiasing delle linee
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);

    // disegno il bordo del poligono
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glBegin(GL_QUADS);
    glTexCoord2d(tex00.x, tex00.y);
    tglVertex(p00);
    glTexCoord2d(tex10.x, tex10.y);
    tglVertex(p10);
    glTexCoord2d(tex11.x, tex11.y);
    tglVertex(p11);
    glTexCoord2d(tex01.x, tex01.y);
    tglVertex(p01);
    glEnd();

    // disabilito l'antialiasing per le linee
    glDisable(GL_LINE_SMOOTH);
    glDisable(GL_BLEND);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
  }

  // force to finish
  glFlush();

  // rimetto il disegno dei poligoni a GL_FILL
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  // metto il frame buffer nel raster del tile
  glPixelStorei(GL_UNPACK_ROW_LENGTH, rasterWidth);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

  TRaster32P newRas(tile.getRaster()->getLx(), tile.getRaster()->getLy());
  newRas->lock();
  glReadPixels(1, 1, newRas->getLx(), newRas->getLy(), GL_RGBA,
               GL_UNSIGNED_BYTE, (void *)newRas->getRawData());
  newRas->unlock();
  checkErrorsByGL

      rasaux->unlock();

  tile.getRaster()->copy(newRas);
}
Esempio n. 18
0
void tglDraw(const TRectD &rect, const TRaster32P &tex, bool blending)
{
	CHECK_ERRORS_BY_GL;
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	if (blending) {
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	unsigned int texWidth = 1;
	unsigned int texHeight = 1;

	while (texWidth < (unsigned int)tex->getLx())
		texWidth = texWidth << 1;

	while (texHeight < (unsigned int)tex->getLy())
		texHeight = texHeight << 1;

	double lwTex = 1.0;
	double lhTex = 1.0;

	TRaster32P texture;
	unsigned int texLx = (unsigned int)tex->getLx();
	unsigned int texLy = (unsigned int)tex->getLy();

	if (texWidth != texLx ||
		texHeight != texLy) {
		texture = TRaster32P(texWidth, texHeight);
		texture->fill(TPixel32(0, 0, 0, 0));
		texture->copy(tex);
		lwTex = (texLx) / (double)(texWidth);
		lhTex = (texLy) / (double)(texHeight);
		if (lwTex > 1.0)
			lwTex = 1.0;
		if (lhTex > 1.0)
			lhTex = 1.0;
	} else
		texture = tex;
	GLenum fmt =
#ifdef TNZ_MACHINE_CHANNEL_ORDER_BGRM
		GL_BGRA_EXT;
#elif TNZ_MACHINE_CHANNEL_ORDER_MBGR
		GL_ABGR_EXT;
#elif TNZ_MACHINE_CHANNEL_ORDER_RGBM
		GL_RGBA;
#elif TNZ_MACHINE_CHANNEL_ORDER_MRGB
		GL_BGRA;
#else
//   Error  PLATFORM NOT SUPPORTED
#error "unknown channel order!"
#endif

	// Generate a texture id and bind it.
	GLuint texId;
	glGenTextures(1, &texId);

	glBindTexture(GL_TEXTURE_2D, texId);

	glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->getWrap());

	texture->lock();
	glTexImage2D(GL_TEXTURE_2D,
				 0,
				 4,
				 texWidth,
				 texHeight,
				 0,
				 fmt,
#ifdef TNZ_MACHINE_CHANNEL_ORDER_MRGB
				 GL_UNSIGNED_INT_8_8_8_8_REV,
#else
				 GL_UNSIGNED_BYTE,
#endif
				 texture->getRawData());

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_TEXTURE_2D);

	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	double rectLx = rect.getLx();
	double rectLy = rect.getLy();

	tglColor(TPixel32(0, 0, 0, 0));

	glPushMatrix();

	glTranslated(rect.x0, rect.y0, 0.0);
	glBegin(GL_POLYGON);

	glTexCoord2d(0, 0);
	tglVertex(TPointD(0.0, 0.0));

	glTexCoord2d(lwTex, 0);
	tglVertex(TPointD(rectLx, 0.0));

	glTexCoord2d(lwTex, lhTex);
	tglVertex(TPointD(rectLx, rectLy));

	glTexCoord2d(0, lhTex);
	tglVertex(TPointD(0.0, rectLy));

	glEnd();
	glDisable(GL_TEXTURE_2D);

	glPopMatrix();
	glPopAttrib();

	// Delete texture
	glDeleteTextures(1, &texId);

	texture->unlock();
}