Exemplo n.º 1
0
CheckerBoard::CheckerBoard(const char* chekerFile)
{

	// Loading the texture object ....
	int y, x;
	int width, height, dummy, r, g, b;
	char p3[6];
	// open file for writing
	FILE *f = fopen(chekerFile, "r");
	if(f == NULL)
	{
		printf("can't open file %s for reading ..", chekerFile);
		return ;
	}
	// write out information required by plain ppm header definition
	fscanf(f, "%s", p3);
	fscanf(f, "%i %i", &width, &height);
	fscanf(f, "%i", &dummy);
	texture_checker.resize(height);
	for(int i = 0 ; i < height ; i++)
	{
		texture_checker[i].resize(width);
	}
	for(y = height-1 ; y >= 0  ; y--)
	{
		for( x = 0 ; x < width; x++)
		{
			fscanf(f, "%i ", &r);
			fscanf(f, "%i ", &g);
			fscanf(f, "%i ", &b);
			texture_checker[y][x][0] = static_cast<float>(r) / 255.0f;
			texture_checker[y][x][1] = static_cast<float>(g) / 255.0f;
			texture_checker[y][x][2] = static_cast<float>(b) / 255.0f;
		}
	}

	// Loading the other verices .. write now hardcoded .. will change it later ..
	vertices[0] = vec3(-3.426671f, -5.225352f, -2.007620f);
	vertices[1] = vec3(21.635147f, 0.822797f, -19.182268f);
	vertices[2] = vec3(-21.635147f, 3.099212f, -25.646494f);
	vertices[3] = vec3(3.426671f, 9.14736f, -42.821140f);

	normals[0] = vec3(0.0000f, 0.187381f, 0.982287f);
	normals[1] = vec3(0.0000f, 0.187381f, 0.982287f);
	normals[2] = vec3(0.0000f, 0.187381f,  0.98229f);
	normals[3] = vec3(0.0000f, 0.187381f, 0.982287f);

	texture_coords[0] = vec2(0.0f, 0.0f);
	texture_coords[1] = vec2(1.0f, 0.0f);
	texture_coords[2] = vec2(0.0f, 1.0f);
	texture_coords[3] = vec2(1.0f, 1.0f);

	faces[0] = uvec3(0, 1, 3);
	faces[1] = uvec3(0, 3, 2);
}
Exemplo n.º 2
0
namespace inviwo {

mat4 getLightTransformationMatrix(vec3 pos, vec3 dir) {
    vec3 A = vec3(0, 0, 1);
    vec3 B = dir;  
    mat4 transformationMatrix;
    // Check if the direction is parallel to the z-axis
    // to avoid division by zero in glm::normalize(glm::cross(A, B)). 
    if (glm::all(glm::lessThan(glm::abs(glm::cross(A, B)), vec3(glm::epsilon<float>())))) {
        // Direction is parallel to z-axis. 
        // Apply rotation by 180 degrees if the direction is along negative z-axis
        float angle = dir.z < 0 ? -static_cast<float>(M_PI) : 0;
        transformationMatrix = glm::translate(pos) * glm::rotate(angle, vec3(0.f, 1.f, 0.f));
    } else {
        float angle = std::acos(glm::dot(A, B));
        vec3 rotationAxis = glm::normalize(glm::cross(A, B));
#ifndef GLM_FORCE_RADIANS
        angle = glm::degrees(angle);
#endif  // GLM_FORCE_RADIANS
        transformationMatrix = glm::translate(pos) * glm::rotate(angle, rotationAxis);
    }
    return transformationMatrix;
}

inviwo::uvec3 LightSource::COLOR_CODE = uvec3(128,64,196);

}
Exemplo n.º 3
0
namespace inviwo {

Buffer::Buffer(size_t size, const DataFormatBase* format, BufferType type, BufferUsage usage)
    : Data(format), size_(size), type_(type), usage_(usage) {}
Buffer::Buffer(const Buffer& rhs)
    : Data(rhs), size_(rhs.size_), type_(rhs.type_), usage_(rhs.usage_) {}

Buffer& Buffer::operator=(const Buffer& that) {
    if (this != &that) {
        Data::operator=(that);
        size_ = that.size_;
        type_ = that.type_;
        usage_ = that.usage_;
    }
    return *this;
}

Buffer* Buffer::clone() const { return new Buffer(*this); }

Buffer::~Buffer() {}

size_t Buffer::getSizeInBytes() { return size_ * dataFormatBase_->getSize(); }

inviwo::uvec3 Buffer::COLOR_CODE = uvec3(255, 113, 0);

const std::string Buffer::CLASS_IDENTIFIER = "org.inviwo.Buffer";

void Buffer::setSize(size_t size) {
    if (size != size_) {
        size_ = size;

        if (lastValidRepresentation_) {
            // Resize last valid representation 
            static_cast<BufferRepresentation*>(lastValidRepresentation_)->setSize(size);

            // and remove the other ones
            util::erase_remove_if(representations_, [this](DataRepresentation* repr) {
                if (repr != lastValidRepresentation_) {
                    delete repr;
                    return true;
                } else {
                    return false;
                }
            });

            setAllRepresentationsAsInvalid();
            // Set the remaining representation as valid.
            // Solves issue where the buffer will try to update 
            // the remaining representation with itself when getRepresentation of the same type is called
            setRepresentationAsValid(0);
        } 
        
    }
}

DataRepresentation* Buffer::createDefaultRepresentation() {
    return createBufferRAM(getSize(), dataFormatBase_, type_, usage_);
}

size_t Buffer::getSize() const {
    // We need to update the size if a representation has changed size
    if (lastValidRepresentation_)
        const_cast<Buffer*>(this)->size_ =
            static_cast<const BufferRepresentation*>(lastValidRepresentation_)->getSize();

    return size_;
}
}
Exemplo n.º 4
0
void init()
{
	setupGL();
  Surface::init();

	cam = new Camera();
  mdl = new Model();

  Mesh mesh = loadMeshFromObj("resources/meshes/dragon.obj", 0.1);
  Geometry dragon = createGeometryFromMesh(mesh);

  Surface *surface = new Surface();
  //surface->loadDiffuseTexture("resources/meshes/textures/sponza_floor_a_spec.tga");
  surfaces.insert(std::pair<std::string, Surface*> (std::string("default"), surface) );

  mdl->addGeometryAndSurface(&dragon, surface);

  // Geometry floor;

  // Geometry::sVertex v;
  // v.position = vec3(-1, 0,-1); v.texCoord = vec2(0,0); floor.addVertex(v);
  // v.position = vec3( 1, 0,-1); v.texCoord = vec2(1,0); floor.addVertex(v);
  // v.position = vec3( 1, 0, 1); v.texCoord = vec2(1,1); floor.addVertex(v);
  // v.position = vec3(-1, 0, 1); v.texCoord = vec2(0,1); floor.addVertex(v);

  // floor.addTriangle(uvec3(0,2,1));
  // floor.addTriangle(uvec3(0,3,2));

  // mdl->addGeometryAndSurface(&floor, surface);

  model = new Geometry();

  mesh = loadMeshFromObj("resources/meshes/sponza.obj", 0.01f);
  *model = createGeometryFromMesh(mesh);
  model->createStaticBuffers();

  std::vector<Mesh> meshes = loadMeshesFromObj("resources/meshes/sponza.obj", 0.01f);
  std::vector<Geometry> geometries = createGeometryFromMesh(meshes);

  std::vector<Material> materials = loadMaterialsFromMtl("resources/meshes/sponza.mtl");
  surfaces = createSurfaceFromMaterial(materials, "resources/meshes/");

  for(unsigned int i=0; i<geometries.size(); ++i)
  {
    mdl->addGeometryAndSurface(&geometries[i], surfaces[geometries[i].material]);
  }

  mdl->prepare();

  fsquad = new Geometry();

  Geometry::sVertex v;
  v.position = vec3(-1,-1, 0); v.texCoord = vec2(0,0); fsquad->addVertex(v);
  v.position = vec3( 1,-1, 0); v.texCoord = vec2(1,0); fsquad->addVertex(v);
  v.position = vec3( 1, 1, 0); v.texCoord = vec2(1,1); fsquad->addVertex(v);
  v.position = vec3(-1, 1, 0); v.texCoord = vec2(0,1); fsquad->addVertex(v);

  fsquad->addTriangle(uvec3(0,1,2));
  fsquad->addTriangle(uvec3(0,2,3));
  fsquad->createStaticBuffers();

	geometryShader = new Shader("resources/shaders/geometry_vert.glsl",
							"resources/shaders/geometry_frag.glsl");

  geometryBackShader = new Shader("resources/shaders/geometry_vert.glsl",
              "resources/shaders/geometry_back_frag.glsl");

  hbaoHalfShader = new Shader("resources/shaders/fullscreen_vert.glsl",
              "resources/shaders/hbao_frag.glsl");

  hbaoFullShader = new Shader("resources/shaders/fullscreen_vert.glsl",
              "resources/shaders/hbao_full_frag.glsl");

	compositShader = new Shader("resources/shaders/fullscreen_vert.glsl",
								"resources/shaders/composit_frag.glsl");

  blurXShader = new Shader("resources/shaders/fullscreen_vert.glsl",
                "resources/shaders/blur_x_frag.glsl");

  blurYShader = new Shader("resources/shaders/fullscreen_vert.glsl",
                "resources/shaders/blur_y_frag.glsl");

  downsampleShader = new Shader("resources/shaders/fullscreen_vert.glsl",
                    "resources/shaders/downsample_depth_frag.glsl");

  upsampleShader = new Shader("resources/shaders/fullscreen_vert.glsl",
                    "resources/shaders/upsample_aoz_frag.glsl");

  // Full res deferred base
  fboFullRes = new Framebuffer2D(WIDTH, HEIGHT);
  fboFullRes->attachBuffer(FBO_DEPTH, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, GL_LINEAR, GL_LINEAR);
  fboFullRes->attachBuffer(FBO_AUX0, GL_RGBA8, GL_RGBA, GL_FLOAT);
  fboFullRes->attachBuffer(FBO_AUX1, GL_RG16F, GL_RG, GL_FLOAT, GL_LINEAR, GL_LINEAR);
  fboFullRes->attachBuffer(FBO_AUX2, GL_RG16F, GL_RG, GL_FLOAT, GL_LINEAR, GL_LINEAR);
  //fboFullRes->attachBuffer(FBO_AUX3, GL_R8, GL_RED, GL_FLOAT);

  // Half res buffer for AO
  fboHalfRes = new Framebuffer2D(AO_WIDTH, AO_HEIGHT);
  //fboHalfRes->attachBuffer(FBO_DEPTH, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT);
  fboHalfRes->attachBuffer(FBO_AUX0, GL_R32F, GL_RED, GL_FLOAT, GL_LINEAR, GL_LINEAR);
  fboHalfRes->attachBuffer(FBO_AUX1, GL_R8, GL_RED, GL_FLOAT, GL_LINEAR, GL_LINEAR);


  float fovRad = cam->getFov() * 3.14159265f / 180.0f;

  vec2 FocalLen, InvFocalLen, UVToViewA, UVToViewB, LinMAD;

  FocalLen[0]      = 1.0f / tanf(fovRad * 0.5f) * ((float)AO_HEIGHT / (float)AO_WIDTH);
  FocalLen[1]      = 1.0f / tanf(fovRad * 0.5f);
  InvFocalLen[0]   = 1.0f / FocalLen[0];
  InvFocalLen[1]   = 1.0f / FocalLen[1];

  UVToViewA[0] = -2.0f * InvFocalLen[0];
  UVToViewA[1] = -2.0f * InvFocalLen[1];
  UVToViewB[0] =  1.0f * InvFocalLen[0];
  UVToViewB[1] =  1.0f * InvFocalLen[1];

  float near = cam->getNear(), far = cam->getFar();
  LinMAD[0] = (near-far)/(2.0f*near*far);
  LinMAD[1] = (near+far)/(2.0f*near*far);

  hbaoHalfShader->bind();
  int pos;
  pos = hbaoHalfShader->getUniformLocation("FocalLen");
  glUniform2f(pos, FocalLen[0], FocalLen[1]);
  pos = hbaoHalfShader->getUniformLocation("UVToViewA");
  glUniform2f(pos, UVToViewA[0], UVToViewA[1]);
  pos = hbaoHalfShader->getUniformLocation("UVToViewB");
  glUniform2f(pos, UVToViewB[0], UVToViewB[1]);
  pos = hbaoHalfShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);

  pos = hbaoHalfShader->getUniformLocation("AORes");
  glUniform2f(pos, (float)AO_WIDTH, (float)AO_HEIGHT);
  pos = hbaoHalfShader->getUniformLocation("InvAORes");
  glUniform2f(pos, 1.0f/(float)AO_WIDTH, 1.0f/(float)AO_HEIGHT);

  pos = hbaoHalfShader->getUniformLocation("R");
  glUniform1f(pos, AO_RADIUS);
  pos = hbaoHalfShader->getUniformLocation("R2");
  glUniform1f(pos, AO_RADIUS*AO_RADIUS);
  pos = hbaoHalfShader->getUniformLocation("NegInvR2");
  glUniform1f(pos, -1.0f / (AO_RADIUS*AO_RADIUS));
  pos = hbaoHalfShader->getUniformLocation("MaxRadiusPixels");
  glUniform1f(pos, AO_MAX_RADIUS_PIXELS / (float)RES_RATIO);

  pos = hbaoHalfShader->getUniformLocation("NoiseScale");
  glUniform2f(pos, (float)AO_WIDTH/(float)NOISE_RES, (float)AO_HEIGHT/(float)NOISE_RES);
  pos = hbaoHalfShader->getUniformLocation("NumDirections");
  glUniform1i(pos, AO_DIRS);
  pos = hbaoHalfShader->getUniformLocation("NumSamples");
  glUniform1i(pos, AO_SAMPLES);

  hbaoFullShader->bind();
  pos = hbaoFullShader->getUniformLocation("FocalLen");
  glUniform2f(pos, FocalLen[0], FocalLen[1]);
  pos = hbaoFullShader->getUniformLocation("UVToViewA");
  glUniform2f(pos, UVToViewA[0], UVToViewA[1]);
  pos = hbaoFullShader->getUniformLocation("UVToViewB");
  glUniform2f(pos, UVToViewB[0], UVToViewB[1]);
  pos = hbaoFullShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);

  pos = hbaoFullShader->getUniformLocation("AORes");
  glUniform2f(pos, (float)WIDTH, (float)HEIGHT);
  pos = hbaoFullShader->getUniformLocation("InvAORes");
  glUniform2f(pos, 1.0f/(float)WIDTH, 1.0f/(float)HEIGHT);

  pos = hbaoFullShader->getUniformLocation("R");
  glUniform1f(pos, AO_RADIUS);
  pos = hbaoFullShader->getUniformLocation("R2");
  glUniform1f(pos, AO_RADIUS*AO_RADIUS);
  pos = hbaoFullShader->getUniformLocation("NegInvR2");
  glUniform1f(pos, -1.0f / (AO_RADIUS*AO_RADIUS));
  pos = hbaoFullShader->getUniformLocation("MaxRadiusPixels");
  glUniform1f(pos, AO_MAX_RADIUS_PIXELS);

  pos = hbaoFullShader->getUniformLocation("NoiseScale");
  glUniform2f(pos, (float)WIDTH/(float)NOISE_RES, (float)HEIGHT/(float)NOISE_RES);
  pos = hbaoFullShader->getUniformLocation("NumDirections");
  glUniform1i(pos, AO_DIRS);
  pos = hbaoFullShader->getUniformLocation("NumSamples");
  glUniform1i(pos, AO_SAMPLES);

  blurXShader->bind();
  pos = blurXShader->getUniformLocation("AORes");
  glUniform2f(pos, AO_WIDTH, AO_HEIGHT);
  pos = blurXShader->getUniformLocation("InvAORes");
  glUniform2f(pos, 1.0f/AO_WIDTH, 1.0f/AO_HEIGHT);
  pos = blurXShader->getUniformLocation("FullRes");
  glUniform2f(pos, WIDTH, HEIGHT);
  pos = blurXShader->getUniformLocation("InvFullRes");
  glUniform2f(pos, 1.0f/WIDTH, 1.0f/HEIGHT);
  pos = blurXShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);

  blurYShader->bind();
  pos = blurYShader->getUniformLocation("AORes");
  glUniform2f(pos, AO_WIDTH, AO_HEIGHT);
  pos = blurYShader->getUniformLocation("InvAORes");
  glUniform2f(pos, 1.0f/AO_WIDTH, 1.0f/AO_HEIGHT);
  pos = blurYShader->getUniformLocation("FullRes");
  glUniform2f(pos, WIDTH, HEIGHT);
  pos = blurYShader->getUniformLocation("InvFullRes");
  glUniform2f(pos, 1.0f/WIDTH, 1.0f/HEIGHT);
  pos = blurYShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);

  downsampleShader->bind();
  pos = downsampleShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);
  pos = downsampleShader->getUniformLocation("ResRatio");
  glUniform1i(pos, RES_RATIO);

  upsampleShader->bind();
  pos = upsampleShader->getUniformLocation("LinMAD");
  glUniform2f(pos, LinMAD[0], LinMAD[1]);

  glGenTextures(1, &noiseTexture);
  glBindTexture(GL_TEXTURE_2D, noiseTexture);
  generateNoiseTexture(NOISE_RES, NOISE_RES);

}
Exemplo n.º 5
0
namespace inviwo {

Volume::Volume(size3_t dimensions, const DataFormatBase* format)
    : Data<VolumeRepresentation>(format), StructuredGridEntity<3>(dimensions), dataMap_(format) {}

Volume::Volume(const Volume& rhs)
    : Data<VolumeRepresentation>(rhs), StructuredGridEntity<3>(rhs), dataMap_(rhs.dataMap_) {}

Volume::Volume(std::shared_ptr<VolumeRepresentation> in)
    : Data<VolumeRepresentation>(in->getDataFormat())
    , StructuredGridEntity<3>(in->getDimensions())
    , dataMap_(in->getDataFormat()) {
    addRepresentation(in);
}

Volume& Volume::operator=(const Volume& that) {
    if (this != &that) {
        Data<VolumeRepresentation>::operator=(that);
        StructuredGridEntity<3>::operator=(that);
        dataMap_ = that.dataMap_;
    }

    return *this;
}
Volume* Volume::clone() const { return new Volume(*this); }
Volume::~Volume() = default;

std::string Volume::getDataInfo() const {
    using P = Document::PathComponent;
    using H = utildoc::TableBuilder::Header;
    Document doc;
    doc.append("b", "Volume", { {"style", "color:white;"} });
    utildoc::TableBuilder tb(doc.handle(), P::end());

    tb(H("Format"), getDataFormat()->getString());
    tb(H("Dimension"), getDimensions());
    tb(H("Data Range"), dataMap_.dataRange);
    tb(H("Value Range"), dataMap_.valueRange);
    tb(H("Unit"), dataMap_.valueUnit);

    if (hasRepresentation<VolumeRAM>()) {
        auto volumeRAM = getRepresentation<VolumeRAM>();
        if (volumeRAM->hasHistograms()) {
            auto histograms = volumeRAM->getHistograms();
            for (size_t i = 0; i < histograms->size(); ++i) {
                std::stringstream ss;
                ss << "Channel " << i << " Min: " << (*histograms)[i].stats_.min
                    << " Mean: " << (*histograms)[i].stats_.mean
                    << " Max: " << (*histograms)[i].stats_.max
                    << " Std: " << (*histograms)[i].stats_.standardDeviation;
                tb(H("Stats"), ss.str());

                std::stringstream ss2;
                ss2 << "(1: " << (*histograms)[i].stats_.percentiles[1]
                    << ", 25: " << (*histograms)[i].stats_.percentiles[25]
                    << ", 50: " << (*histograms)[i].stats_.percentiles[50]
                    << ", 75: " << (*histograms)[i].stats_.percentiles[75]
                    << ", 99: " << (*histograms)[i].stats_.percentiles[99] << ")";
                tb(H("Percentiles"), ss2.str());
            }
        }
    }
    return doc;
}

size3_t Volume::getDimensions() const {
    if (hasRepresentations() && lastValidRepresentation_) {
        return lastValidRepresentation_->getDimensions();
    }
    return StructuredGridEntity<3>::getDimensions();
}

void Volume::setDimensions(const size3_t& dim) {
    StructuredGridEntity<3>::setDimensions(dim);

    if (lastValidRepresentation_) {
        // Resize last valid representation
        lastValidRepresentation_->setDimensions(dim);
        removeOtherRepresentations(lastValidRepresentation_.get());
    }
}

void Volume::setOffset(const vec3& offset) {
    SpatialEntity<3>::setOffset(Vector<3, float>(offset));
}
vec3 Volume::getOffset() const { return SpatialEntity<3>::getOffset(); }

mat3 Volume::getBasis() const { return SpatialEntity<3>::getBasis(); }
void Volume::setBasis(const mat3& basis) { SpatialEntity<3>::setBasis(Matrix<3, float>(basis)); }

mat4 Volume::getModelMatrix() const { return SpatialEntity<3>::getModelMatrix(); }
void Volume::setModelMatrix(const mat4& mat) {
    SpatialEntity<3>::setModelMatrix(Matrix<4, float>(mat));
}

mat4 Volume::getWorldMatrix() const { return SpatialEntity<3>::getWorldMatrix(); }
void Volume::setWorldMatrix(const mat4& mat) {
    SpatialEntity<3>::setWorldMatrix(Matrix<4, float>(mat));
}

std::shared_ptr<VolumeRepresentation> Volume::createDefaultRepresentation() const {
    return createVolumeRAM(getDimensions(), getDataFormat());
}


vec3 Volume::getWorldSpaceGradientSpacing() const {
    mat3 textureToWorld = mat3(getCoordinateTransformer().getTextureToWorldMatrix());
    // Basis vectors with a length of one voxel.
    // Basis vectors may be non-orthogonal
    auto dimensions = getDimensions();
    vec3 a = textureToWorld[0] / static_cast<float>(dimensions[0]);
    vec3 b = textureToWorld[1] / static_cast<float>(dimensions[1]);
    vec3 c = textureToWorld[2] / static_cast<float>(dimensions[2]);
    // Project the voxel basis vectors 
    // onto the world space x/y/z axes,
    // and choose the longest projected vector
    // for each axis.
    // Using the fact that
    // vec3 x{ 1.f, 0, 0 };
    // vec3 y{ 0, 1.f, 0 };
    // vec3 z{ 0, 0, 1.f };
    // such that 
    // ax' = dot(x, a) = a.x
    // bx' = dot(x, b) = b.x
    // cx' = dot(x, c) = c.x
    // and so on.
    auto signedMax = [](const float &x1, const float &x2) {
        return (std::abs(x1) >= std::abs(x2)) ? x1 : x2;
    };

    vec3 ds{ 
        signedMax(a.x, signedMax(b.x, c.x)),
        signedMax(a.y, signedMax(b.y, c.y)),
        signedMax(a.z, signedMax(b.z, c.z)) };

    // Return the spacing in world space,
    // actually given by:
    // { gradientSpacing.x         0                     0
    //         0             gradientSpacing.y           0
    //         0                   0               gradientSpacing.z }
    return ds;
}

inviwo::uvec3 Volume::COLOR_CODE = uvec3(188, 101, 101);
const std::string Volume::CLASS_IDENTIFIER = "org.inviwo.Volume";

const StructuredCameraCoordinateTransformer<3>& Volume::getCoordinateTransformer(
    const Camera& camera) const {
    return StructuredGridEntity<3>::getCoordinateTransformer(camera);
}

}  // namespace
Exemplo n.º 6
0
TEST(PickingTests, GenerateIndex1) {
    auto i1 = PickingManager::colorToIndex(uvec3(39, 98, 118));
    EXPECT_EQ(i1, 1);
}
Exemplo n.º 7
0
TEST(PickingTests, GenerateIndex0) {
    auto i0 = PickingManager::colorToIndex(uvec3(19, 177, 59));
    EXPECT_EQ(i0, 0);
}
Exemplo n.º 8
0
TEST(PickingTests, GenerateColor1) {
    auto c1 = PickingManager::indexToColor(1);
    EXPECT_EQ(c1, uvec3(39, 98, 118));
}
Exemplo n.º 9
0
TEST(PickingTests, GenerateColor0) {
    auto c0 = PickingManager::indexToColor(0);
    EXPECT_EQ(c0, uvec3(19, 177, 59));
}