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); }
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); }
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_; } }
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); }
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
TEST(PickingTests, GenerateIndex1) { auto i1 = PickingManager::colorToIndex(uvec3(39, 98, 118)); EXPECT_EQ(i1, 1); }
TEST(PickingTests, GenerateIndex0) { auto i0 = PickingManager::colorToIndex(uvec3(19, 177, 59)); EXPECT_EQ(i0, 0); }
TEST(PickingTests, GenerateColor1) { auto c1 = PickingManager::indexToColor(1); EXPECT_EQ(c1, uvec3(39, 98, 118)); }
TEST(PickingTests, GenerateColor0) { auto c0 = PickingManager::indexToColor(0); EXPECT_EQ(c0, uvec3(19, 177, 59)); }