Add a world generator based on another raytracer file format I made in the past and add a crude tool to run it.

it does not render properly, there are some major differences between both engine especially in the material definition. Will need more work, but is not urgent.
This commit is contained in:
Godzil
2020-02-22 15:16:25 +00:00
parent 4d4c4a7453
commit c9021974f6
4 changed files with 335 additions and 225 deletions

View File

@@ -10,6 +10,7 @@
#define DORAYME_WORLDBUILDER_H #define DORAYME_WORLDBUILDER_H
#include <world.h> #include <world.h>
#include <camera.h>
/* Let's keep a single header for now, will see later */ /* Let's keep a single header for now, will see later */
@@ -22,7 +23,30 @@ public:
/* Not implemented yet */ /* Not implemented yet */
class Hw3File : public World class Hw3File : public World
{ {
private:
Matrix transformStack[50];
uint32_t transStackCount;
public: public:
double currentAmbient;
double currentShininess;
double currentSpecular;
double currentDiffuse;
double currentEmission;
double currentReflective;
double currentTransparency;
double currentRefIndex;
Colour currentColour;
Matrix cam;
double camFoV;
public:
Matrix getTransformMatrix();
void popTransformMatrix();
void pushTransformMatrix();
void applyTransformMatrix(Matrix t);
Hw3File(const char *filename); Hw3File(const char *filename);
}; };

View File

@@ -7,18 +7,20 @@
* *
*/ */
/* Don't build for now */ /* Don't build for now */
#if 0
/* This file is parsing a text format from another raytracer I made in the past. */ /* This file is parsing a text format from another raytracer I made in the past. */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h>
#include <ctype.h> #include <ctype.h>
#include <math.h>
#include <worldbuilder.h>
#include <sphere.h>
#include <matrix.h>
#include <transformation.h>
#define IS_CMD(_cmd) (strncmp(buffer, _cmd, sizeof(_cmd)) == 0) #define IS_CMD(_cmd) (strncmp(buffer, _cmd, sizeof(_cmd)) == 0)
typedef void (*cmdFunc)(scene *sc, uint32_t curLine, char *first, float argv[15]); typedef void (*cmdFunc)(Hw3File *w, uint32_t curLine, double argv[15]);
typedef struct cmd_def typedef struct cmd_def
{ {
@@ -27,111 +29,127 @@ typedef struct cmd_def
cmdFunc f; cmdFunc f;
} cmd_def; } cmd_def;
void cmdCamera (scene *sc, uint32_t curLine, char *first, float argv[15]) static void cmdCamera (Hw3File *w, uint32_t curLine, double argv[15])
{ {
sc->cam.seteye(point(argv[0], argv[1], argv[2])); w->cam = viewTransform(Point(argv[0], argv[1], argv[2]),
sc->cam.setat(point(argv[3], argv[4], argv[5])); Point(argv[3], argv[4], argv[5]),
sc->cam.setup(vector(argv[6], argv[7], argv[8])); Vector(argv[6], argv[7], argv[8]));
sc->cam.setfovy(argv[9]);
w->camFoV = deg_to_rad(argv[9]);
} }
void cmdSphere (scene *sc, uint32_t curLine, char *first, float argv[15]) /* 0: X, 1: Y, 2: Z
* 3: Radius
*/
static void cmdSphere (Hw3File *w, uint32_t curLine, double argv[15])
{ {
printf("Adding a sphere...\n");
/* Instanciate a sphere */ /* Instanciate a sphere */
sphere *sp = new sphere(point(argv[0], argv[1], argv[2]), argv[3], sc->getMatrix()); Sphere *shape = new Sphere();
sp->ambient = sc->ambient;
sp->diffuse = sc->diffuse; Matrix pos = translation(argv[0], argv[1], argv[2]) * scaling(argv[3], argv[3], argv[3]);
sp->specular = sc->specular;
sp->emission = sc->emission; shape->setTransform(w->getTransformMatrix() * pos);
sp->shininess = sc->shininess;
sp->sourceLine = curLine; shape->material.ambient = w->currentAmbient;
sc->o[sc->o_count] = sp; shape->material.reflective = w->currentReflective;
sc->o_count++; shape->material.shininess = w->currentShininess;
shape->material.specular = w->currentSpecular;
shape->material.diffuse = w->currentDiffuse;
shape->material.colour = w->currentColour;
shape->material.transparency = w->currentTransparency;
shape->material.refractiveIndex = w->currentRefIndex;
w->addObject(shape);
} }
void cmdCube (scene *sc, uint32_t curLine, char *first, float argv[15]) static void cmdCube (Hw3File *w, uint32_t curLine, double argv[15])
{ {
} }
static void cmdTrans (Hw3File *w, uint32_t curLine, double argv[15])
{
Matrix m = translation(argv[0], argv[1], argv[2]);
w->applyTransformMatrix(m);
}
static void cmdRotate (Hw3File *w, uint32_t curLine, double argv[15])
{
Matrix m = Matrix4().identity();
if (argv[2] != 0)
{
m = m * rotationZ(argv[3]);
}
if (argv[1] != 0)
{
m = m * rotationY(argv[3]);
}
if (argv[0] != 0)
{
m = m * rotationX(argv[3]);
}
w->applyTransformMatrix(m);
}
static void cmdScale (Hw3File *w, uint32_t curLine, double argv[15])
{
Matrix m = scaling(argv[0], argv[1], argv[2]);
w->applyTransformMatrix(m);
}
static void cmdPushT (Hw3File *w, uint32_t curLine, double argv[15])
{
w->pushTransformMatrix();
}
static void cmdPopT (Hw3File *w, uint32_t curLine, double argv[15])
{
w->popTransformMatrix();
}
static void cmdLPoint (Hw3File *w, uint32_t curLine, double argv[15])
{
/* create point light */
Light *l = new Light(POINT_LIGHT, Point(argv[0], argv[1], argv[2]), Colour(argv[3], argv[4], argv[5]));
w->addLight(l);
}
static void cmdAmbient (Hw3File *w, uint32_t curLine, double argv[15])
{
//w->currentAmbient = (argv[0] + argv[1] + argv[2]) / 3;
w->currentColour = Colour(argv[0], argv[1], argv[2]);
}
static void cmdColour (Hw3File *w, uint32_t curLine, double argv[15])
{
w->currentColour = Colour(argv[0], argv[1], argv[2]);
}
static void cmdDiffuse (Hw3File *w, uint32_t curLine, double argv[15])
{
w->currentDiffuse = (argv[0] + argv[1] + argv[2]) / 3;
}
static void cmdSpecular (Hw3File *w, uint32_t curLine, double argv[15])
{
w->currentSpecular = (argv[0] + argv[1] + argv[2]) / 3;
}
static void cmdShine (Hw3File *w, uint32_t curLine, double argv[15])
{
w->currentReflective = argv[0];
}
static void cmdEmission (Hw3File *w, uint32_t curLine, double argv[15])
{
w->currentEmission = (argv[0] + argv[1] + argv[2]) / 3;
}
#if 0 #if 0
void cmdMaxVerts (scene *sc, uint32_t curLine, char *first, float argv[15]) static void cmdLDire (Hw3File *w, uint32_t curLine, double argv[15])
{
sc->vertexCount = (uint32_t) argv[0];
sc->vertex = new point[sc->vertexCount];
sc->curVertex = 0;
}
void cmdMaxVertN (scene *sc, uint32_t curLine, char *first, float argv[15])
{
/* ignore for now */
}
void cmdVertex (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]);
sc->curVertex++;
}
void cmdVertexN (scene *sc, uint32_t curLine, char *first, float argv[15])
{
/* ignore for now */
}
void cmdTri (scene *sc, uint32_t curLine, char *first, float argv[15])
{
/* arg are vertex numbers */
triangle *tr = new triangle(sc->vertex[(int)argv[0]], sc->vertex[(int)argv[1]], sc->vertex[(int)argv[2]], sc->getMatrix());
tr->ambient = sc->ambient;
tr->diffuse = sc->diffuse;
tr->specular = sc->specular;
tr->emission = sc->emission;
tr->shininess = sc->shininess;
tr->sourceLine = curLine;
sc->o[sc->o_count] = tr;
sc->o_count++;
}
void cmdTriN (scene *sc, uint32_t curLine, char *first, float argv[15])
{
/* ignore for noz */
}
#endif
void cmdTrans (scene *sc, uint32_t curLine, char *first, float argv[15])
{
matrix m;
m.translation(argv[0], argv[1], argv[2]);
sc->applyTransform(m);
}
void cmdRotate (scene *sc, uint32_t curLine, char *first, float argv[15])
{
matrix m;
vector axis;
axis.set(argv[0], argv[1], argv[2]);
m.rotation(axis, argv[3]);
sc->applyTransform(m);
}
void cmdScale (scene *sc, uint32_t curLine, char *first, float argv[15])
{
matrix m;
m.scale(argv[0], argv[1], argv[2]);
sc->applyTransform(m);
}
void cmdPushT (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->pushMatrix();
}
void cmdPopT (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->popMatrix();
}
#if 0
void cmdLDire (scene *sc, uint32_t curLine, char *first, float argv[15])
{ {
/* create directional light */ /* create directional light */
light *cur = new light(); light *cur = new light();
@@ -145,60 +163,56 @@ void cmdLDire (scene *sc, uint32_t curLine, char *first, float argv[15])
sc->l[sc->l_count] = cur; sc->l[sc->l_count] = cur;
sc->l_count++; sc->l_count++;
} }
#endif
void cmdLPoint (scene *sc, uint32_t curLine, char *first, float argv[15]) static void cmdAtten (Hw3File *w, uint32_t curLine, double argv[15])
{ {
/* create point light */ sc->attenuation = Vector(argv[0], argv[1], argv[2]);
light *cur = new light();
cur->type = LIGHT_POINT;
cur->attenuation = sc->attenuation;
cur->position.set(argv[0], argv[1], argv[2]);
cur->lightcolor.set(argv[3], argv[4], argv[5]);
sc->l[sc->l_count] = cur;
sc->l_count++;
} }
#if 0 static void cmdMaxVerts (Hw3File *w, uint32_t curLine, double argv[15])
void cmdAtten (scene *sc, uint32_t curLine, char *first, float argv[15])
{ {
sc->attenuation = vector(argv[0], argv[1], argv[2]); sc->vertexCount = (uint32_t) argv[0];
sc->vertex = new point[sc->vertexCount];
sc->curVertex = 0;
}
static void cmdMaxVertN (Hw3File *w, uint32_t curLine, double argv[15])
{
/* ignore for now */
}
static void cmdVertex (Hw3File *w, uint32_t curLine, double argv[15])
{
sc->vertex[sc->curVertex].set(argv[0], argv[1], argv[2]);
sc->curVertex++;
}
static void cmdVertexN (Hw3File *w, uint32_t curLine, double argv[15])
{
/* ignore for now */
}
static void cmdTri (Hw3File *w, uint32_t curLine, double argv[15])
{
/* arg are vertex numbers */
triangle *tr = new triangle(sc->vertex[(int)argv[0]], sc->vertex[(int)argv[1]], sc->vertex[(int)argv[2]], sc->getMatrix());
tr->ambient = sc->ambient;
tr->diffuse = sc->diffuse;
tr->specular = sc->specular;
tr->emission = sc->emission;
tr->shininess = sc->shininess;
tr->sourceLine = curLine;
sc->o[sc->o_count] = tr;
sc->o_count++;
} }
#endif #endif
void cmdAmbient (scene *sc, uint32_t curLine, char *first, float argv[15]) static cmd_def commandList[] =
{ {
sc->ambient = color(argv[0], argv[1], argv[2]);
}
void cmdDiffuse (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->diffuse = color(argv[0], argv[1], argv[2]);
}
void cmdSpecular (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->specular = color(argv[0], argv[1], argv[2]);
}
void cmdShine (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->shininess = argv[0];
}
void cmdEmission (scene *sc, uint32_t curLine, char *first, float argv[15])
{
sc->emission = color(argv[0], argv[1], argv[2]);
}
cmd_def commandList[] =
{
/* Camera */ /* Camera */
{ "camera", 10, cmdCamera }, {"camera", 10, cmdCamera},
/* Geometry */ /* Geometry */
{ "sphere", 4, cmdSphere }, {"sphere", 4, cmdSphere},
//{ "maxverts", 1, cmdMaxVerts }, //{ "maxverts", 1, cmdMaxVerts },
//{ "maxvertnorms", 1, cmdMaxVertN }, //{ "maxvertnorms", 1, cmdMaxVertN },
//{ "vertex", 3, cmdVertex }, //{ "vertex", 3, cmdVertex },
@@ -207,56 +221,59 @@ cmd_def commandList[] =
//{ "trinormal", 3, cmdTriN }, //{ "trinormal", 3, cmdTriN },
//{ "cube", 1, cmdCube }, //{ "cube", 1, cmdCube },
/* transformation */ /* transformation */
{ "translate", 3, cmdTrans }, {"translate", 3, cmdTrans},
{ "rotate", 4, cmdRotate }, {"rotate", 4, cmdRotate},
{ "scale", 3, cmdScale }, {"scale", 3, cmdScale},
{ "pushTransform", 0, cmdPushT }, {"pushTransform", 0, cmdPushT},
{ "popTransform", 0, cmdPopT }, {"popTransform", 0, cmdPopT},
/* Lights */ /* Lights */
//{ "directional", 6, cmdLDire }, //{ "directional", 6, cmdLDire },
{ "point", 6, cmdLPoint }, {"point", 6, cmdLPoint},
//{ "attenuation", 3, cmdAtten }, //{ "attenuation", 3, cmdAtten },
/* Materials */ /* Materials */
{ "ambient", 3, cmdAmbient }, {"color", 3, cmdColour},
{ "diffuse", 3, cmdDiffuse }, {"ambient", 3, cmdAmbient},
{ "specular", 3, cmdSpecular }, {"diffuse", 3, cmdDiffuse},
{ "shininess", 1, cmdShine }, {"specular", 3, cmdSpecular},
{ "emission", 3, cmdEmission }, {"shininess", 1, cmdShine},
}; {"emission", 3, cmdEmission},
};
#define CMD_COUNT (sizeof(commandList) / sizeof(cmd_def)) #define CMD_COUNT (sizeof(commandList) / sizeof(cmd_def))
scene *readfile::read(char *filename) Hw3File::Hw3File(const char *filename) : transStackCount(0), currentColour(Colour(1, 1, 1)),
currentEmission(0), currentShininess(200), currentAmbient(0.1),
currentDiffuse(0.9), currentSpecular(0.9), camFoV(0)
{ {
FILE *fp; FILE *fp;
scene *sc = new scene;
if (sc != NULL) this->popTransformMatrix();
{
fp = fopen(filename, "rt"); fp = fopen(filename, "rt");
if (fp == NULL) if (fp != NULL)
{
delete sc;
sc = NULL;
}
else
{ {
char buffer[512]; char buffer[512];
int line = 0; int line = 0;
while(!feof(fp)) while(!feof(fp))
{ {
uint32_t i; uint32_t i;
line++; line++;
memset(buffer, 0, 512); memset(buffer, 0, 512);
fgets(buffer, 512, fp); fgets(buffer, 512, fp);
if ((buffer[0] == '#') || (strlen(buffer) < 2)) if ((buffer[0] == '#') || (strlen(buffer) < 2))
{
continue; /* Ingore empty line or commented lines */ continue; /* Ingore empty line or commented lines */
//printf("::%d:> %s", strlen(buffer), buffer); }
for (i = 0; i < CMD_COUNT; i++) for (i = 0; i < CMD_COUNT; i++)
{ {
if (strncmp(buffer, commandList[i].name, strlen(commandList[i].name)) == 0) if (strncmp(buffer, commandList[i].name, strlen(commandList[i].name)) == 0)
{ {
char first[512]; char first[512];
float value[15]; double value[15];
if (commandList[i].numparam != 0) if (commandList[i].numparam != 0)
{ {
size_t j; size_t j;
@@ -285,23 +302,45 @@ scene *readfile::read(char *filename)
if (k != abs(commandList[i].numparam)) if (k != abs(commandList[i].numparam))
{ {
printf("line %d malformed: given %d parameter, expected %d\n%s", line, k, abs(commandList[i].numparam), buffer); printf("line %d malformed: given %d parameter, expected %d\n%s", line, k, abs(commandList[i].numparam), buffer);
sc = NULL;
goto exit; goto exit;
} }
} }
commandList[i].f(sc, line, first, value); commandList[i].f(this, line, value);
break; break;
} }
} }
} }
#ifdef USE_OCTREE
sc->createOctree();
#endif
}
} }
exit: exit:
return sc; return;
} }
#endif Matrix Hw3File::getTransformMatrix()
{
return this->transformStack[this->transStackCount];
}
void Hw3File::popTransformMatrix()
{
if (this->transStackCount == 0)
{
this->transformStack[0] = Matrix4().identity();
}
else
{
this->transformStack[this->transStackCount] = Matrix4().identity();
this->transStackCount --;
}
}
void Hw3File::pushTransformMatrix()
{
this->transStackCount ++;
this->transformStack[this->transStackCount] = this->transformStack[this->transStackCount - 1];
}
void Hw3File::applyTransformMatrix(Matrix t)
{
this->transformStack[this->transStackCount] = this->transformStack[this->transStackCount] * t;
}

View File

@@ -19,6 +19,11 @@ gtest_discover_tests(testMyRays
) )
add_executable(hw3render)
target_include_directories(hw3render PUBLIC ../source/include)
target_sources(hw3render PRIVATE hw3render.cpp)
target_link_libraries(hw3render rayonnement)
add_executable(ch5_test) add_executable(ch5_test)
target_include_directories(ch5_test PUBLIC ../source/include) target_include_directories(ch5_test PUBLIC ../source/include)
target_sources(ch5_test PRIVATE ch5_test.cpp) target_sources(ch5_test PRIVATE ch5_test.cpp)

42
tests/hw3render.cpp Normal file
View File

@@ -0,0 +1,42 @@
/*
* DoRayMe - a quick and dirty Raytracer
* Renderer using hw3 files as world builder.
*
* Created by Manoël Trapier
* Copyright (c) 2020 986-Studio.
*
*/
#include <stdio.h>
#include <world.h>
#include <worldbuilder.h>
#include <light.h>
#include <sphere.h>
#include <material.h>
#include <colour.h>
#include <canvas.h>
#include <camera.h>
#include <transformation.h>
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("usage: %s file.hw3\n", argv[0]);
return -1;
}
Hw3File world = Hw3File(argv[1]);
/* Set the camera resolution */
Camera cam = Camera(640, 480, world.camFoV);
cam.setTransform(world.cam);
/* Now render it */
Canvas image = cam.render(world);
image.SaveAsPNG("hw3render.png");
return 0;
}