Reputation: 47
I am currently working on a raytracer, and I am trying to output the result using multiple ways at the same time (only through PPM format and using SFML atm).
To achieve that, I wrote an IOutput
interface that gets inherited by the classes corresponding to each way of rendering an image.
Here is the problematic piece of code:
#ifndef PPM_FILE_HPP_
#define PPM_FILE_HPP_
// #include "../Core/math.hpp"
#include <tuple>
#include <array>
#include <string>
#include <fstream>
#include <sstream>
namespace Math {
class Vector3D {
public:
double x, y, z;
Vector3D() : x(0), y(0), z(0) {}
Vector3D(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {}
};
}
template <int width, int height>
class IOutput {
public:
IOutput() : is_rendered(false) {}
virtual void refresh() = 0;
virtual void set_pixel(std::tuple<int, int> location, Math::Vector3D color) = 0;
virtual void set_as_rendered() = 0;
protected:
std::array<std::array<Math::Vector3D, width>, height> grid;
bool is_rendered = false;
};
template <int width, int height>
class PPM_file : public IOutput<width, height> {
public:
PPM_file(std::string filename) : IOutput<width, height>(), file(filename), color_depth(255)
{
if (!file.is_open())
throw std::runtime_error("Unable to open file: " + filename);
file << "P3\n" << width << " " << height << "\n" << color_depth << "\n";
}
~PPM_file()
{
if (!this->is_rendered)
set_as_rendered();
if (file.is_open())
file.close();
}
void refresh() override {};
void set_pixel(std::tuple<int, int> location, Math::Vector3D color) override
{
int x = std::get<0>(location);
int y = std::get<1>(location);
if (x >= 0 && x < width && y >= 0 && y < height) {
this->grid[y][x] = color;
} else {
std::cerr << "Error: Pixel location (" << x << ", " << y << ") is out of bounds." << std::endl;
}
}
void set_as_rendered() override
{
this->is_rendered = true;
for (const auto& row : this->grid) {
for (const auto& pixel : row) {
file << vec3_to_string(pixel);
}
}
file.close();
}
protected:
std::ofstream file;
int color_depth;
private:
std::string vec3_to_string(Math::Vector3D vector)
{
std::ostringstream ss;
ss << static_cast<int>(vector.x * 255) << " "
<< static_cast<int>(vector.y * 255) << " "
<< static_cast<int>(vector.z * 255) << "\n";
return ss.str();
}
};
#endif /* !PPM_FILE_HPP_ */
here is a sample main function that makes the program segfault
#include "src/Output/PPM_file.hpp"
int main()
{
std::cout << "This line will never get executed, the program crashes as soon as a function containing the problematic piece of code is called" << std::endl;
PPM_file<800, 600> test_file("image.ppm");
return 0;
}
For some reasons, the segfault disapears when I remove the inheritance from IOutput
and remove everything linked to IOutput
in PPM_file
, so I assume it is somehow linked but I can't figure out how
Upvotes: 1
Views: 48