Reorganize Fitness
- background color - functions to load shader and target - split up rendering and evaluating chromosomes
This commit is contained in:
parent
bd45691996
commit
764b26c611
3 changed files with 124 additions and 40 deletions
2
Makefile
2
Makefile
|
|
@ -10,7 +10,7 @@ SRCDIR = src
|
||||||
TMPDIR = build
|
TMPDIR = build
|
||||||
TARGET = gross
|
TARGET = gross
|
||||||
#FILES = Chromosome Fitness Generation main
|
#FILES = Chromosome Fitness Generation main
|
||||||
FILES = Genes Chromosome
|
FILES = Genes Chromosome Fitness main
|
||||||
|
|
||||||
#SOURCES = $(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
|
#SOURCES = $(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
|
||||||
OBJECTS = $(patsubst %,$(TMPDIR)/%.o,$(FILES))
|
OBJECTS = $(patsubst %,$(TMPDIR)/%.o,$(FILES))
|
||||||
|
|
|
||||||
142
src/Fitness.cpp
142
src/Fitness.cpp
|
|
@ -4,36 +4,21 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fitness::Fitness(sf::Texture target) :
|
sf::Color Fitness::backgroundColor = sf::Color::White;
|
||||||
|
|
||||||
|
|
||||||
|
Fitness::Fitness() :
|
||||||
dummy(sf::TriangleFan, 4)
|
dummy(sf::TriangleFan, 4)
|
||||||
{
|
{
|
||||||
this->target = target;
|
|
||||||
sf::Vector2u targetSize = this->target.getSize();
|
|
||||||
this->tex.create(targetSize.x, targetSize.y);
|
|
||||||
|
|
||||||
this->horizontal = targetSize.x >= targetSize.y;
|
|
||||||
if (this->horizontal) {
|
|
||||||
targetSize.x = 1;
|
|
||||||
} else {
|
|
||||||
targetSize.y = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->comp.create(targetSize.x, targetSize.y);
|
|
||||||
// this->comp.setSmooth(true);
|
|
||||||
|
|
||||||
this->dummy[0] = sf::Vertex(sf::Vector2f(0, 0), sf::Color::Red );
|
|
||||||
this->dummy[1] = sf::Vertex(sf::Vector2f(targetSize.x, 0), sf::Color::Yellow);
|
|
||||||
this->dummy[2] = sf::Vertex(sf::Vector2f(targetSize), sf::Color::Green );
|
|
||||||
this->dummy[3] = sf::Vertex(sf::Vector2f(0, targetSize.y), sf::Color::Blue );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Fitness::loadShader(std::string filename)
|
bool Fitness::loadShader(std::string filename)
|
||||||
{
|
{
|
||||||
this->compshdr.loadFromFile(filename, sf::Shader::Fragment);
|
this->shaderLoaded = this->compshdr.loadFromFile(filename, sf::Shader::Fragment);
|
||||||
if (this->compshdr.isAvailable()) {
|
if (this->shaderLoaded) {
|
||||||
this->compshdr.setUniform("base", this->target);
|
this->compshdr.setUniform("base", this->target.getTexture());
|
||||||
this->compshdr.setUniform("curr", this->tex.getTexture());
|
this->compshdr.setUniform("curr", this->chromosome.getTexture());
|
||||||
this->compshdr.setUniform("size", sf::Vector2f(this->target.getSize()));
|
this->compshdr.setUniform("size", sf::Vector2f(this->target.getSize()));
|
||||||
this->compshdr.setUniform("horizontal", this->horizontal);
|
this->compshdr.setUniform("horizontal", this->horizontal);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -43,13 +28,94 @@ bool Fitness::loadShader(std::string filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long long Fitness::of(const Chromosome& chr)
|
bool Fitness::loadTarget(std::string filename)
|
||||||
{
|
{
|
||||||
// first, render chr to a texture, so we can just compare two textures
|
// so create() isn't called twice on the same RenderTextures
|
||||||
this->tex.clear();
|
// if (this->targetLoaded) {
|
||||||
this->tex.draw(chr);
|
// TODO: Test if this is necessary
|
||||||
this->tex.display();
|
|
||||||
|
// DANGER ZONE :P
|
||||||
|
// First call destructor of object, then create new instance of object
|
||||||
|
// because the RenderTexture doesn't support this->target = RenderTexture();
|
||||||
|
|
||||||
|
// Do not separate these lines!
|
||||||
|
// this->target.~RenderTexture();
|
||||||
|
// new (&this->target) sf::RenderTexture();
|
||||||
|
|
||||||
|
// Do not separate these lines!
|
||||||
|
// this->comp.~RenderTexture();
|
||||||
|
// new (&this->comp) sf::RenderTexture();
|
||||||
|
|
||||||
|
// Do not separate these lines!
|
||||||
|
// this->chromosome.~RenderTexture();
|
||||||
|
// new (&this->chromosome) sf::RenderTexture();
|
||||||
|
// }
|
||||||
|
|
||||||
|
this->targetLoaded = false;
|
||||||
|
|
||||||
|
// load the image
|
||||||
|
sf::Texture tex;
|
||||||
|
if (!tex.loadFromFile("tom-face.png")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create render textures in the needed size
|
||||||
|
sf::Vector2u targetSize = tex.getSize();
|
||||||
|
if (!this->target.create(targetSize.x, targetSize.y)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this->chromosome.create(targetSize.x, targetSize.y)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// render target image to render texture
|
||||||
|
sf::Sprite spr(tex);
|
||||||
|
this->target.clear(Fitness::backgroundColor);
|
||||||
|
this->target.draw(spr);
|
||||||
|
this->target.display();
|
||||||
|
|
||||||
|
// do "horizontal" stuff
|
||||||
|
this->horizontal = targetSize.x >= targetSize.y;
|
||||||
|
if (this->horizontal) {
|
||||||
|
targetSize.x = 1;
|
||||||
|
} else {
|
||||||
|
targetSize.y = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create render texture needed for computing fitness
|
||||||
|
if (!this->comp.create(targetSize.x, targetSize.y)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set dummy vertices to comp dimensions
|
||||||
|
// the colors don't matter, so why not rainbow 'em?
|
||||||
|
this->dummy[0] = sf::Vertex(sf::Vector2f(0, 0), sf::Color::Red );
|
||||||
|
this->dummy[1] = sf::Vertex(sf::Vector2f(targetSize.x, 0), sf::Color::Yellow);
|
||||||
|
this->dummy[2] = sf::Vertex(sf::Vector2f(targetSize), sf::Color::Green );
|
||||||
|
this->dummy[3] = sf::Vertex(sf::Vector2f(0, targetSize.y), sf::Color::Blue );
|
||||||
|
|
||||||
|
// update shader uniforms
|
||||||
|
if (this->shaderLoaded) {
|
||||||
|
this->compshdr.setUniform("size", sf::Vector2f(this->target.getSize()));
|
||||||
|
this->compshdr.setUniform("horizontal", this->horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yay, loading sucessful!
|
||||||
|
this->targetLoaded = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fitness::render(const Chromosome& chr)
|
||||||
|
{
|
||||||
|
this->chromosome.clear(Fitness::backgroundColor);
|
||||||
|
this->chromosome.draw(chr);
|
||||||
|
this->chromosome.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long long Fitness::compute()
|
||||||
|
{
|
||||||
// compare the two textures using the SUPER ADVANCED shader
|
// compare the two textures using the SUPER ADVANCED shader
|
||||||
this->comp.clear(sf::Color::Blue);
|
this->comp.clear(sf::Color::Blue);
|
||||||
this->comp.draw(this->dummy, &this->compshdr);
|
this->comp.draw(this->dummy, &this->compshdr);
|
||||||
|
|
@ -59,22 +125,30 @@ unsigned long long Fitness::of(const Chromosome& chr)
|
||||||
sf::Image image = this->comp.getTexture().copyToImage();
|
sf::Image image = this->comp.getTexture().copyToImage();
|
||||||
sf::Vector2u size = image.getSize();
|
sf::Vector2u size = image.getSize();
|
||||||
|
|
||||||
|
// TODO: Deal with horizontal-ness properly (not this ↓ ugly)
|
||||||
unsigned long long fitness = 0;
|
unsigned long long fitness = 0;
|
||||||
if (this->horizontal) {
|
if (this->horizontal) {
|
||||||
for (unsigned int y=0; y<size.y; ++y) {
|
for (unsigned int y=0; y<size.y; ++y) {
|
||||||
sf::Color col = image.getPixel(0, y);
|
sf::Color col = image.getPixel(0, y);
|
||||||
fitness += (unsigned long long)col.r; // 2^(8*0) - first byte
|
fitness += (unsigned long long)col.r; // 2^(8*0) - first byte
|
||||||
fitness += (unsigned long long)col.g*256; // 2^(8*1) - second byte
|
fitness += (unsigned long long)col.g*256; // 2^(8*1) - second byte
|
||||||
fitness += (unsigned long long)col.b*65536; // 2^(8*2) - third byte
|
fitness += (unsigned long long)col.b*65536; // 2^(8*2) - third byte
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (unsigned int x=0; x<size.x; ++x) {
|
for (unsigned int x=0; x<size.x; ++x) {
|
||||||
sf::Color col = image.getPixel(x, 0);
|
sf::Color col = image.getPixel(x, 0);
|
||||||
fitness += (unsigned long long)col.r; // 2^(8*0) - first byte
|
fitness += (unsigned long long)col.r; // 2^(8*0) - first byte
|
||||||
fitness += (unsigned long long)col.g*256; // 2^(8*1) - second byte
|
fitness += (unsigned long long)col.g*256; // 2^(8*1) - second byte
|
||||||
fitness += (unsigned long long)col.b*65536; // 2^(8*2) - third byte
|
fitness += (unsigned long long)col.b*65536; // 2^(8*2) - third byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fitness;
|
return fitness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long long Fitness::of(const Chromosome& chr)
|
||||||
|
{
|
||||||
|
this->render(chr);
|
||||||
|
return this->compute();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,28 @@
|
||||||
class Fitness
|
class Fitness
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Fitness(sf::Texture target);
|
static sf::Color backgroundColor;
|
||||||
|
|
||||||
|
Fitness();
|
||||||
bool loadShader(std::string filename);
|
bool loadShader(std::string filename);
|
||||||
|
bool loadTarget(std::string filename);
|
||||||
|
|
||||||
unsigned long long of(const Chromosome& chr);
|
void render(const Chromosome& chr);
|
||||||
|
unsigned long long compute();
|
||||||
|
|
||||||
|
unsigned long long of(const Chromosome& chr); // uses render and compute
|
||||||
|
|
||||||
|
sf::RenderTexture target; // contains image to compare against
|
||||||
|
sf::RenderTexture chromosome; // contains the Chromosome to be evaluated
|
||||||
|
|
||||||
sf::Texture target; // base image to compare against
|
|
||||||
sf::RenderTexture tex; // big RenderWindow containg the Chromosome to be evaluated
|
|
||||||
sf::RenderTexture comp; // smaller RenderWindow which is downloaded as Image
|
sf::RenderTexture comp; // smaller RenderWindow which is downloaded as Image
|
||||||
|
|
||||||
sf::VertexArray dummy;
|
|
||||||
bool horizontal;
|
bool horizontal;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool shaderLoaded = false;
|
||||||
|
bool targetLoaded = false;
|
||||||
|
|
||||||
sf::Shader compshdr; // shader to perform pixel-wise image diff with
|
sf::Shader compshdr; // shader to perform pixel-wise image diff with
|
||||||
|
sf::VertexArray dummy; // something to render so that the shader is run on every pixel
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue