I am having some problems with my ray-tracing program. The initial code I used was from the youtube tutorial - https://www.youtube.com/watch?v=k_aRiYSXcyo (caleb piercy tutorial on ray-tracing).
I then re-made the code in the main.cpp into a object-oriented code using Visual Studio.
The point was to encapsulate the functions and calculations in order then to use either OpenMP(in Visual Studio) or (in Visual Studio) so that i can multi-thread the whole program.
But before I do that I am having a problem with the specific declarations of the variables. Most of them are declarations of vectors from my Vect.h header file and Camera.h file.
Here is the code from the main.cpp and more specifically - just the declarations. I will not post the algorithm functions and calculations since they work and I don't have a problem with them.
the class in which i declare some of the variables and method functions
//thread class
class Thread
{
public:
void UPrightRend();
void UPleftRend();
void DownrightRend();
void DownleftRend();
void define();
void calcVect(int x, int y);
void calcColor();
void saveimg(const char *filename);
int winningObjectIndex(vector<double> object_intersections);
Color getColorAt(Vect intersection_position, Vect intersecting_ray_direction, vector<Object*> scene_objects, int index_of_winning_object, vector<Source*> light_sources, double accuracy, double ambientlight);
private:
//basic variables
int dpi = 72;
double sWidth = 1000;
double sHeight = 800;
int n = sWidth*sHeight;
RGBType *pixels = new RGBType[n];
//aadepth sends out n number of pixels/rays that hit one pixels and then reflect to other pixels are return a value that is then averaged
static const int aadepth = 5;
double aspectratio = sWidth / sHeight;
double ambientlight = 0.2;
double accuracy = 0.000001;
int thisone, aa_index;
double xamnt, yamnt;
Vect camdir;
Vect camright;
Vect camdown;
Camera scene_cam;
vector<Source*> light_sources;
vector<Object*> scene_objects;
//start with a blank pixel
double tempRed[aadepth*aadepth];
double tempGreen[aadepth*aadepth];
double tempBlue[aadepth*aadepth];
};
and the deceleration of the other variables.
void Thread::define()
{
//Calling Vect.h and establishing the XYZ positions
Vect O(0, 0, 0);
Vect X(3, 0, 3.5);
Vect Y(0, 1, 0);
Vect Z(0, 0, 1);
Vect P(5.5, 0, 3.5);
Vect R(0, -3, 0);
Vect M(7, 0, -5);
Vect new_sphere_location(2, 0, 0);
Vect campos(4, 1, -4);
Vect look_at(0, 0, 0);
Vect diff_btw(campos.getVectX() - look_at.getVectX(), campos.getVectY() - look_at.getVectY(), campos.getVectZ() - look_at.getVectZ());
//camera direction and position
camdir = diff_btw.negative().normalize();
camright = Y.crossProduct(camdir).normalize();
camdown = camright.crossProduct(camdir);
Camera scene_cam(campos, camdir, camright, camdown);
//color of objects and planes
Color white_light(1.0, 1.0, 1.0, 0);
Color pretty_green(0.25, 0.25, 0.95, 0.5);
Color maroon(0.5, 0.25, 0.25, 0.5);
Color tile_floor(1, 1, 1, 2);
Color gray(0.5, 0.5, 0.5, 0);
Color black(0.0, 0.0, 0.0, 0);
//light color and position
Vect light_position(-7, 10, -10);
Light scene_light(light_position, white_light);
light_sources.push_back(dynamic_cast<Source*>(&scene_light));
//scene objects
Sphere scene_sphere(O, 0.85, pretty_green);
Sphere scene_sphere2(new_sphere_location, 0.5, maroon);
Plane scene_plane(Y, -1, tile_floor);
Plane scene_plane2(P, -1, gray);
Plane scene_plane3(X, 1, gray);
Plane scene_plane4(R, -1, tile_floor);
Plane scene_plane5(M, -1, black);
scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere));
scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere2));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane2));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane3));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane4));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane5));
}
So.
When I call the define()
function in the main()
function with an object, I get a black screen as an image output. When I call the define()
function in the calculation function, then the program crashes immediately on start.
If i move the contents of the define()
function into the class private:
, the I get errors for the declarations.
All of the variables in the define()
have to be seen but I do not know how to do it.
How do I fix this? It doesn't work and i just get a black screen image as a result or it just crashes.
Sorry if something is unclear.(this is my first question on stackoverflow).
Thank you!
I don't know, exactly, where is the problem that cause the black screen but I'm not surprised about the crash.
You should consider that variables (and relative values) declared in a method, as in define()
, are lost when the method end it's execution.
So look the following code
Sphere scene_sphere(O, 0.85, pretty_green);
Sphere scene_sphere2(new_sphere_location, 0.5, maroon);
Plane scene_plane(Y, -1, tile_floor);
Plane scene_plane2(P, -1, gray);
Plane scene_plane3(X, 1, gray);
Plane scene_plane4(R, -1, tile_floor);
Plane scene_plane5(M, -1, black);
scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere));
scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere2));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane2));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane3));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane4));
scene_objects.push_back(dynamic_cast<Object*>(&scene_plane5));
You declare seven local variables (scene_sphere
, scene_sphere2
, etc.) and next you add their pointer (I suppose that Object
is a base class for Sphere
and Plane
) in a member of the class (scene_objects
).
When define()
end it's execution, the seven variables (scene_sphere
, scene_sphere2
, etc.) end their life and their memory is freed. So the seven pointers in scene_objects
are pointing to freed stack memory that can be recycled for other different variables.
When you try (if you try) to use one of the seven pointers, it's very very likely that the program crash.
Same problem with
Light scene_light(light_position, white_light);
light_sources.push_back(dynamic_cast<Source*>(&scene_light));
I suppose you should use the dynamic allocation (new
) in this way
light_sources.push_back(new Light(light_position, white_light));
// ...
scene_objects.push_back(new Sphere(O, 0.85, pretty_green));
scene_objects.push_back(new Sphere(new_sphere_location, 0.5, maroon));
scene_objects.push_back(new Plane(Y, -1, tile_floor));
scene_objects.push_back(new Plane(P, -1, gray));
scene_objects.push_back(new Plane(X, 1, gray));
scene_objects.push_back(new Plane(R, -1, tile_floor));
scene_objects.push_back(new Plane(M, -1, black));
so the pointed object can survive the end of define()
.
But remember to delete
they when appropriate, if you don't want leak memory.
Or, better, you can use smart pointers (std::unique_ptr
by example) instead of simple pointers.
p.s.: sorry for my bad English