// Description: Testing for textures
// DocumentationOf: textures.h
#include "test/test_init.h"
#include <test/pastel/gfx/test_pastelgfx.h>
#include "pastel/sys/array.h"
#include "pastel/sys/view.h"
#include "pastel/sys/extender/indexextenders.h"
#include "pastel/gfx/color.h"
#include "pastel/gfx/texture.h"
#include "pastel/gfx/drawing.h"
#include "pastel/gfx/image_file.h"
#include "pastel/gfx/mipmap.h"
#include "pastel/gfx/ripmap.h"
#include "pastel/gfx/filter.h"
#include "pastel/sys/string.h"
#include "pastel/geometry/planar_projection.h"
#include <boost/bind.hpp>
#include <memory>
#include <iostream>
TEST_CASE("EwaMagnification (Texture)")
{
integer Width = 400;
integer Height = 400;
Array<Color>* textureImagePtr = gfxStorage().get<Array<Color>*>("lena_image");
ENSURE(textureImagePtr);
Array<Color>& textureImage = *textureImagePtr;
MipMap<Color, 2> mipMap(constArrayView(textureImage),
ArrayExtender<2, Color>(clampExtender()));
transform(mipMap, fitColor);
Array<Color, 2> image(Vector2i(Width * 2, Height * 2));
AlignedBox2 textureBox(0.4, 0.45, 0.55, 0.60);
AlignedBox2 box(0, 0, Width, Height);
{
NearestImage_Texture<Color> texture(textureImage,
ArrayExtender<2, Color>(clampExtender()));
drawTexturedBox(
box + Vector2(0, Height),
texture,
arrayView(image),
textureBox);
}
{
LinearImage_Texture<Color> texture(textureImage);
drawTexturedBox(
box + Vector2(Width, Height),
texture,
arrayView(image),
textureBox);
}
{
EwaImage_Texture<Color> texture(mipMap,
ArrayExtender<2, Color>(clampExtender()),
gaussianFilter(1));
drawTexturedBox(
box + Vector2(0, 0),
texture,
arrayView(image),
textureBox);
}
{
EwaImage_Texture<Color> texture(mipMap,
ArrayExtender<2, Color>(clampExtender()),
lanczosFilter(2));
drawTexturedBox(
box + Vector2(Width, 0),
texture,
arrayView(image),
textureBox);
}
transform(arrayView(image), fitColor);
savePcx(image, "texture_ewa_magnification.pcx");
}
TEST_CASE("EwaMagnification2 (Texture)")
{
integer Width = 400;
integer Height = 400;
Array<Color, 2> textureImage(Vector2i(40, 40));
integer CheckerWidth = 20;
integer CheckerHeight = 20;
for (integer y = 0;y < textureImage.height();++y)
{
for (integer x = 0;x < textureImage.width();++x)
{
const integer xMod = mod(x, 2 * CheckerWidth);
const integer yMod = mod(y, 2 * CheckerHeight);
if ((xMod < CheckerWidth) !=
(yMod >= CheckerHeight))
{
textureImage(x, y) = Color(1);
}
else
{
textureImage(x, y) = Color(0);
}
}
}
/*
Array<Color, 2> textureImage;
loadPcx("texture_checker.pcx", textureImage);
//loadPcx("lena.pcx", textureImage);
*/
MipMap<Color, 2> mipMap(constArrayView(textureImage),
ArrayExtender<2, Color>(clampExtender()));
transform(mipMap, fitColor);
Array<Color, 2> image(Vector2i(Width, Height));
using TexturePtr = std::shared_ptr<Texture<Color>>;
std::vector<TexturePtr> textureList;
textureList.push_back(
TexturePtr(new EwaImage_Texture<Color>(mipMap,
ArrayExtender<2, Color>(clampExtender()),
gaussianFilter(1))));
textureList.push_back(
TexturePtr(new EwaImage_Texture<Color>(mipMap,
ArrayExtender<2, Color>(clampExtender()),
gaussianFilter(2))));
textureList.push_back(
TexturePtr(new EwaImage_Texture<Color>(mipMap,
ArrayExtender<2, Color>(clampExtender()),
lanczosFilter(2))));
textureList.push_back(
TexturePtr(new EwaImage_Texture<Color>(mipMap,
ArrayExtender<2, Color>(clampExtender()),
boxFilter())));
textureList.push_back(
TexturePtr(new LinearImage_Texture<Color>(textureImage,
ArrayExtender<2, Color>(clampExtender()))));
textureList.push_back(
TexturePtr(new NearestImage_Texture<Color>(textureImage,
ArrayExtender<2, Color>(clampExtender()))));
AlignedBox2 textureBox(0.4, 0.4, 0.6, 0.6);
AlignedBox2 box(0, 0, Width, Height);
integer textures = textureList.size();
for (integer i = 0;i < textures;++i)
{
drawTexturedBox(
box + Vector2(0, 0),
*textureList[i],
arrayView(image),
textureBox);
transform(arrayView(image), fitColor);
savePcx(image, "texture_checker3_" + textureList[i]->name() +
"_" + integerToString(i) + ".pcx");
}
}
TEST_CASE("Samplers (Texture)")
{
Array<Color, 2> image(Vector2i(750, 500));
Array<Color, 2> textureImage;
loadPcx("lena.pcx", textureImage);
MipMap<Color, 2> mipMap(constArrayView(textureImage),
ArrayExtender<2, Color>(clampExtender()));
transform(mipMap, fitColor);
MipImage_Texture<Color> mipmapSampler(mipMap);
Color colorSet[] =
{
Color(1, 1, 1),
Color(1, 0, 0),
Color(0, 1, 0),
Color(0, 0, 1)
};
drawTexturedBox(
AlignedBox2(0, 400, 100, 500),
linearColorTexture<Color, 2>(
range(colorSet)),
arrayView(image));
drawTexturedBox(
AlignedBox2(150, 400, 250, 500),
colorTexture<Color, 2>(Color(0.5, 0, 1)),
arrayView(image));
// Comparison of filtering techniques.
drawTexturedBox(
AlignedBox2(0, 250, 100, 350),
nearestImageTexture(textureImage),
arrayView(image));
drawTexturedBox(
AlignedBox2(150, 250, 250, 350),
mipmapSampler,
arrayView(image));
EwaImage_Texture<Color> texture(mipMap);
drawTexturedBox(
AlignedBox2(450, 250, 550, 350),
texture,
arrayView(image));
// Something else.
/*
drawTexturedBox(
AlignedBox2(0, 0, 200, 200),
nearestImageTexture(clampedConstView(constSubView(constArrayView(textureImage), AlignedBox2i(100, 100, 150, 150)))),
arrayView(image));
drawTexturedBox(
AlignedBox2(250, 0, 450, 200),
linearImageTexture(clampedConstView(constSubView(constArrayView(textureImage), AlignedBox2i(100, 100, 150, 150)))),
arrayView(image));
*/
drawTexturedBox(
AlignedBox2(100, 100, 300, 225),
mipmapSampler,
arrayView(image),
AlignedBox2(0, 0, 1, 1),
transparentColorMixer<Color>(0.25));
drawView(
constSubView(constArrayView(textureImage), AlignedBox2i(200, 200, 300, 300)),
Vector2i(300, 400),
arrayView(image));
savePcx(image, "textures_texturebox.pcx");
clear(Color(0), arrayView(image));
drawTexturedBox(
AlignedBox2(0, 0, 500, 500),
nearestImageTexture(textureImage, ArrayExtender<2, Color>(clampExtender())),
arrayView(image),
AlignedBox2(0.5, 0.5, 5.0, 5.0));
savePcx(image, "textures_clampedtexturebox.pcx");
drawTexturedBox(
AlignedBox2(0, 0, 500, 500),
nearestImageTexture(textureImage, ArrayExtender<2, Color>(repeatExtender())),
arrayView(image),
AlignedBox2(0.5, 0.5, 5.0, 5.0));
savePcx(image, "textures_repeatedtexturebox.pcx");
drawTexturedBox(
AlignedBox2(0, 0, 500, 500),
nearestImageTexture(textureImage, ArrayExtender<2, Color>(mirrorExtender())),
arrayView(image),
AlignedBox2(0.5, 0.5, 5.0, 5.0));
savePcx(image, "textures_mirroredtexturebox.pcx");
drawTexturedBox(
AlignedBox2(0, 0, 500, 500),
nearestImageTexture(textureImage),
arrayView(image),
AlignedBox2(0.5, 0.5, 5.0, 5.0));
savePcx(image, "textures_borderedtexturebox.pcx");
}
namespace
{
void drawTestQuad(
const Tuple<Vector2, 4>& quad,
const Tuple<Vector2, 4>& textureQuad,
const Texture<Color>& texture,
const std::string& testName,
const std::string& name)
{
real yMax = -(real)Infinity();
for (integer i = 0;i < 4;++i)
{
if (quad[i].y() > yMax)
{
yMax = quad[i].y();
}
}
Array<Color, 2> image(Vector2i(500, ceil(yMax)));
drawProjectiveQuad(
quad,
texture,
arrayView(image),
textureQuad);
savePcx(image, "texture_" + testName + "_" + name + ".pcx");
}
}
TEST_CASE("Checker (Texture)")
{
Array<Color, 2> image(Vector2i(500, 500));
Array<Color, 2> textureImage(Vector2i(40, 40));
integer CheckerWidth = 20;
integer CheckerHeight = 20;
for (integer y = 0;y < textureImage.height();++y)
{
for (integer x = 0;x < textureImage.width();++x)
{
const integer xMod = mod(x, 2 * CheckerWidth);
const integer yMod = mod(y, 2 * CheckerHeight);
if ((xMod < CheckerWidth) !=
(yMod >= CheckerHeight))
{
textureImage(x, y) = Color(1);
}
else
{
textureImage(x, y) = Color(0);
}
}
}
savePcx(textureImage, "texture_checker.pcx");
MipMap<Color, 2> mipMap(constArrayView(textureImage),
ArrayExtender<2, Color>(repeatExtender()), boxFilter());
transform(mipMap, fitColor);
RipMap<Color, 2> ripMap(constArrayView(textureImage));
transform(ripMap, fitColor);
Array<Color, 2> lenaTextureImage;
loadPcx("lena.pcx", lenaTextureImage);
MipMap<Color, 2> lenaMipMap(constArrayView(lenaTextureImage));
transform(lenaMipMap, fitColor);
RipMap<Color, 2> lenaRipMap(constArrayView(lenaTextureImage));
transform(lenaRipMap, fitColor);
ConstIndexExtenderPtr extender = repeatExtender();
EwaImage_Texture<Color> textureEwaGaussian1(
mipMap, ArrayExtender<2, Color>(extender), gaussianFilter(1));
EwaImage_Texture<Color> textureEwaGaussian2(
mipMap, ArrayExtender<2, Color>(extender), gaussianFilter(2));
EwaImage_Texture<Color> textureEwaLanczos2(
mipMap, ArrayExtender<2, Color>(extender), lanczosFilter(2));
EwaImage_Texture<Color> textureEwaMitchell(
mipMap, ArrayExtender<2, Color>(extender), mitchellFilter());
EwaImage_Texture<Color> textureEwaBox(
mipMap, ArrayExtender<2, Color>(extender), boxFilter());
EwaImage_Texture<Color> textureEwaTriangle(
mipMap, ArrayExtender<2, Color>(extender), triangleFilter());
MipImage_Texture<Color> textureMip(
mipMap, ArrayExtender<2, Color>(extender));
RipImage_Texture<Color> textureRip(
ripMap, ArrayExtender<2, Color>(extender));
std::vector<std::pair<std::string, Texture<Color>*> > textureList;
textureList.emplace_back(std::string("ewa_gaussian1"), (Texture<Color>*)&textureEwaGaussian1);
textureList.emplace_back(std::string("ewa_gaussian2"), (Texture<Color>*)&textureEwaGaussian2);
textureList.emplace_back(std::string("ewa_lanczos2"), (Texture<Color>*)&textureEwaLanczos2);
textureList.emplace_back(std::string("ewa_mitchell"), (Texture<Color>*)&textureEwaMitchell);
textureList.emplace_back(std::string("ewa_box"), (Texture<Color>*)&textureEwaBox);
textureList.emplace_back(std::string("ewa_triangle"), (Texture<Color>*)&textureEwaTriangle);
textureList.emplace_back(std::string("mip"), (Texture<Color>*)&textureMip);
textureList.emplace_back(std::string("rip"), (Texture<Color>*)&textureRip);
integer textures = textureList.size();
{
Tuple<Vector2, 4> quad(
Vector2(250, 0),
Vector2(500, 150),
Vector2(250, 175),
Vector2(0, 150));
Tuple<Vector2, 4> textureQuad(
Vector2(0, 0),
Vector2(2, 0),
Vector2(2, 2),
Vector2(0, 2));
for (integer i = 0;i < textures;++i)
{
drawTestQuad(quad, textureQuad, *textureList[i].second,
"checker1", textureList[i].first);
}
}
/*
MipMap<Color, 2> distortMipMap(constArrayView(image));
EwaImage_Texture<Color> distortTexture(distortMipMap);
transform(distortMipMap, fitColor);
clear(Color(0), arrayView(image));
drawProjectiveQuad(
Tuple<Vector2, 4>(
Vector2(0, 0),
Vector2(500, 0),
Vector2(500, 500),
Vector2(0, 500)),
distortTexture,
arrayView(image),
Tuple<Vector2, 4>(
Vector2(0.5, 0),
Vector2(1, (real)150 / 500),
Vector2(0.5, (real)175 / 500),
Vector2(0, (real)150 / 500)));
savePcx(image, "texture_checker1_distorted2x.pcx");
*/
mipMap.swap(lenaMipMap);
ripMap.swap(lenaRipMap);
for (integer i = 0;i < textures;++i)
{
Tuple<Vector2, 4> quad(
Vector2(250, 0),
Vector2(500, 150),
Vector2(250, 175),
Vector2(0, 150));
Tuple<Vector2, 4> textureQuad(
Vector2(0, 0),
Vector2(1, 0),
Vector2(1, 1),
Vector2(0, 1));
drawTestQuad(quad, textureQuad, *textureList[i].second,
"lena1", textureList[i].first);
}
/*
MipMap<Color, 2> distortMipMap(constArrayView(image));
EwaImage_Texture<Color> distortTexture(distortMipMap);
transform(distortMipMap, fitColor);
clear(Color(0), arrayView(image));
drawProjectiveQuad(
Tuple<Vector2, 4>(
Vector2(0, 0),
Vector2(500, 0),
Vector2(500, 500),
Vector2(0, 500)),
distortTexture,
arrayView(image),
Tuple<Vector2, 4>(
Vector2(0.5, 0),
Vector2(1, (real)150 / 500),
Vector2(0.5, (real)175 / 500),
Vector2(0, (real)150 / 500)));
savePcx(image, "texture_lena1_ewa_distorted2x.pcx");
*/
mipMap.swap(lenaMipMap);
ripMap.swap(lenaRipMap);
{
Tuple<Vector2, 4> quad(
Vector2(0, 0),
Vector2(500, 0),
Vector2(255, 150),
Vector2(245, 150));
Tuple<Vector2, 4> textureQuad(
Vector2(0, 0),
Vector2(20, 0),
Vector2(20, 800),
Vector2(0, 800));
for (integer i = 0;i < textures;++i)
{
drawTestQuad(quad, textureQuad, *textureList[i].second,
"checker2", textureList[i].first);
}
}
/*
{
clear(Color(0), arrayView(image));
Tuple<Vector2, 4> quad(
Vector2(0, 0),
Vector2(500, 0),
Vector2(300, 250),
Vector2(200, 250));
Tuple<Vector2, 4> textureQuad(
Vector2(0, 0),
Vector2(10, 0),
Vector2(10, 100),
Vector2(0, 100));
clear(Color(0), arrayView(image));
EwaImage_Texture<Color> texture(mipMap);
drawProjectiveQuad(
quad,
mixTexture(
colorTexture<Color>(Color(0)),
transformTexture(
mixTexture(
linearImageTexture(repeatedConstView(constArrayView(lenaTextureImage))),
colorTexture<Color>(Color(1)),
linearColorTexture<real>(0, 0, 1, 1)),
AffineTransformation<real>(identityMatrix<Real>(2, 2) * 10, Vector2())),
texture),
arrayView(image),
textureQuad);
savePcx(image, "texture_texture_mix.pcx");
}
*/
}
TEST_CASE("Mix (Texture)")
{
Array<Color, 2> aTexture;
loadPcx("lena.pcx", aTexture);
Array<Color, 2> bTexture;
loadPcx("kodak_test_images/kodim19.pcx", bTexture);
Array<Color, 2> image(Vector2i(750, 750), Color(0));
MipMap<Color, 2> aMipMap(constArrayView(aTexture));
transform(aMipMap, fitColor);
MipMap<Color, 2> bMipMap(constArrayView(bTexture));
transform(bMipMap, fitColor);
integer iconSize = 250;
integer iconSpace = iconSize;
AlignedBox2 iconBox(0, 0, iconSize, iconSize);
drawTexturedBox(
iconBox + Vector2(0, 0),
combineTexture(
mipImageTexture(aMipMap),
mipImageTexture(bMipMap),
transparentColorMixer<Color>(0.5)),
arrayView(image));
drawTexturedBox(
iconBox + Vector2(iconSpace, 0),
combineTexture(
mipImageTexture(aMipMap),
mipImageTexture(bMipMap),
functorColorMixer<Color>(std::minus<Color>())),
arrayView(image));
drawTexturedBox(
iconBox + Vector2(iconSpace, iconSpace),
combineTexture(
mipImageTexture(aMipMap),
mipImageTexture(bMipMap),
functorColorMixer<Color>(std::plus<Color>())),
arrayView(image));
drawTexturedBox(
iconBox + Vector2(0, iconSpace),
combineTexture(
mipImageTexture(aMipMap),
mipImageTexture(bMipMap),
functorColorMixer<Color>(std::multiplies<Color>())),
arrayView(image));
drawTexturedBox(
iconBox + Vector2(0, iconSpace * 2),
mipImageTexture(aMipMap),
arrayView(image));
drawTexturedBox(
iconBox + Vector2(iconSpace * 2, 0),
mipImageTexture(bMipMap),
arrayView(image));
savePcx(image, "texture_mix.pcx");
}