Reorganize Fitness

- background color
- functions to load shader and target
- split up rendering and evaluating chromosomes
This commit is contained in:
Joscha 2017-05-12 11:16:06 +00:00
parent bd45691996
commit 764b26c611
3 changed files with 124 additions and 40 deletions

View file

@ -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))

View file

@ -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,6 +125,7 @@ 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) {
@ -78,3 +145,10 @@ unsigned long long Fitness::of(const Chromosome& chr)
return fitness; return fitness;
} }
unsigned long long Fitness::of(const Chromosome& chr)
{
this->render(chr);
return this->compute();
}

View file

@ -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
}; };