#include "shader.hpp"


ShaderInfo::ShaderInfo(unsigned ww, unsigned hh)
    : buf((shader_info_t*)calloc(ww*hh, sizeof(shader_info_t))), w(ww), h(hh) {
}


ShaderInfo::~ShaderInfo() {
    free(buf);
}

void ShaderInfo::reset() {
    memset((void*)buf, 0, w*h*sizeof(shader_info_t));
}


std::vector<PixelShader*> PixelShader::insts;


PixelShader::PixelShader() {
    insts.push_back(this);
}


void PixelShader::get_all(const Scene* s, ShaderInfo::shader_info_t& i, Img::rgb_t& p) {
    for (std::vector<PixelShader*>::iterator it=insts.begin(); it!=insts.end(); ++it) {
        (*it)->get(s, i, p);
    }
}


PixelShader::~PixelShader() {
    for (std::vector<PixelShader*>::iterator it=insts.begin(); it!=insts.end(); ++it) {
        if (*it == this) {
            insts.erase(it);
            break;
        }
    }
}


void PixelShader::clear_all() {
    while (insts.size()) {
        delete insts.front();
    }
}


std::vector<ImageShader*> ImageShader::insts;


ImageShader::ImageShader() {
    insts.push_back(this);
}


bool ImageShader::get_all(const Scene* s, ShaderInfo& i, Img& p) {
    if (insts.empty()) return false;
    for (std::vector<ImageShader*>::iterator it=insts.begin(); it!=insts.end(); ++it) {
        (*it)->get(s, i, p);
    }
    return true;
}


ImageShader::~ImageShader() {
    for (std::vector<ImageShader*>::iterator it=insts.begin(); it!=insts.end(); ++it) {
        if (*it == this) {
            insts.erase(it);
            break;
        }
    }
}


void ImageShader::clear_all() {
    while (insts.size()) {
        delete insts.front();
    }
}