Init
This commit is contained in:
commit
3f6ca06228
7 changed files with 281 additions and 0 deletions
21
Makefile
Normal file
21
Makefile
Normal file
|
@ -0,0 +1,21 @@
|
|||
CPP_FILES := $(wildcard src/*.cpp)
|
||||
OBJ_FILES := $(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
|
||||
LD_FLAGS :=
|
||||
CC_FLAGS := -std=gnu++11
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXEC := main.exe
|
||||
else
|
||||
EXEC := main
|
||||
endif
|
||||
|
||||
$(EXEC): $(OBJ_FILES)
|
||||
g++ $(LD_FLAGS) -o $@ $^
|
||||
|
||||
obj/%.o: src/%.cpp
|
||||
mkdir -p obj
|
||||
g++ $(CC_FLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm obj/*
|
||||
rm $(EXEC)
|
BIN
main
Executable file
BIN
main
Executable file
Binary file not shown.
BIN
obj/main.o
Normal file
BIN
obj/main.o
Normal file
Binary file not shown.
10
scene.txt
Normal file
10
scene.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
640 480
|
||||
3 3 2
|
||||
1.0 1.0 0.0 0.5
|
||||
0.0 1.0 1.0 0.5
|
||||
1.0 0.0 1.0 0.5
|
||||
233.0 290.0 0.0 100 0
|
||||
407.0 290.0 0.0 100 1
|
||||
320.0 140.0 0.0 100 2
|
||||
0.0 240.0 -100.0 1.0 1.0 1.0
|
||||
640.0 240.0 -10000.0 0.6 0.7 1.0
|
167
src/main.cpp
Normal file
167
src/main.cpp
Normal file
|
@ -0,0 +1,167 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include "raytracer.h"
|
||||
|
||||
bool init(char* inputName, scene &myScene)
|
||||
{
|
||||
int nbMat, nbSphere, nbLight;
|
||||
int i;
|
||||
ifstream sceneFile(inputName);
|
||||
if (!sceneFile)
|
||||
return false;
|
||||
sceneFile >> myScene.sizex >> myScene.sizey;
|
||||
sceneFile >> nbMat >> nbSphere >> nbLight;
|
||||
myScene.matTab.resize(nbMat);
|
||||
myScene.sphTab.resize(nbSphere);
|
||||
myScene.lgtTab.resize(nbLight);
|
||||
for (i=0; i < nbMat; i++)
|
||||
sceneFile >> myScene.matTab[i];
|
||||
for (i=0; i < nbSphere; i++)
|
||||
sceneFile >> myScene.sphTab[i];
|
||||
for (i=0; i < nbLight; i++)
|
||||
sceneFile >> myScene.lgtTab[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hitSphere(const ray &r, const sphere &s, float &t)
|
||||
{
|
||||
// intersection rayon/sphere
|
||||
vecteur dist = s.pos - r.start;
|
||||
float B = r.dir * dist;
|
||||
float D = B*B - dist * dist + s.size * s.size;
|
||||
if (D < 0.0f)
|
||||
return false;
|
||||
float t0 = B - sqrtf(D);
|
||||
float t1 = B + sqrtf(D);
|
||||
bool retvalue = false;
|
||||
if ((t0 > 0.1f) && (t0 < t))
|
||||
{
|
||||
t = t0;
|
||||
retvalue = true;
|
||||
}
|
||||
if ((t1 > 0.1f) && (t1 < t))
|
||||
{
|
||||
t = t1;
|
||||
retvalue = true;
|
||||
}
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
bool draw(char* outputName, scene &myScene)
|
||||
{
|
||||
ofstream imageFile(outputName,ios_base::binary);
|
||||
if (!imageFile)
|
||||
return false;
|
||||
// Ajout du header TGA
|
||||
imageFile.put(0).put(0);
|
||||
imageFile.put(2); /* RGB non compresse */
|
||||
|
||||
imageFile.put(0).put(0);
|
||||
imageFile.put(0).put(0);
|
||||
imageFile.put(0);
|
||||
|
||||
imageFile.put(0).put(0); /* origine X */
|
||||
imageFile.put(0).put(0); /* origine Y */
|
||||
|
||||
imageFile.put((myScene.sizex & 0x00FF)).put((myScene.sizex & 0xFF00) / 256);
|
||||
imageFile.put((myScene.sizey & 0x00FF)).put((myScene.sizey & 0xFF00) / 256);
|
||||
imageFile.put(24); /* 24 bit bitmap */
|
||||
imageFile.put(0);
|
||||
// fin du header TGA
|
||||
|
||||
// balayage
|
||||
for (int y = 0; y < myScene.sizey; ++y) {
|
||||
for (int x = 0; x < myScene.sizex; ++x) {
|
||||
float red = 0, green = 0, blue = 0;
|
||||
float coef = 1.0f;
|
||||
int level = 0;
|
||||
// lancer de rayon
|
||||
ray viewRay = { {float(x), float(y), -10000.0f}, { 0.0f, 0.0f, 1.0f}};
|
||||
do
|
||||
{
|
||||
// recherche de l'intersection la plus proche
|
||||
float t = 20000.0f;
|
||||
int currentSphere= -1;
|
||||
|
||||
for (unsigned int i = 0; i < myScene.sphTab.size(); ++i)
|
||||
{
|
||||
if (hitSphere(viewRay, myScene.sphTab[i], t))
|
||||
{
|
||||
currentSphere = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSphere == -1)
|
||||
break;
|
||||
|
||||
point newStart = viewRay.start + t * viewRay.dir;
|
||||
// la normale au point d'intersection
|
||||
vecteur n = newStart - myScene.sphTab[currentSphere].pos;
|
||||
float temp = n * n;
|
||||
if (temp == 0.0f)
|
||||
break;
|
||||
|
||||
temp = 1.0f / sqrtf(temp);
|
||||
n = temp * n;
|
||||
|
||||
material currentMat = myScene.matTab[myScene.sphTab[currentSphere].material];
|
||||
|
||||
// calcul de la valeur d'éclairement au point
|
||||
for (unsigned int j = 0; j < myScene.lgtTab.size(); ++j) {
|
||||
light current = myScene.lgtTab[j];
|
||||
vecteur dist = current.pos - newStart;
|
||||
if (n * dist <= 0.0f)
|
||||
continue;
|
||||
float t = sqrtf(dist * dist);
|
||||
if ( t <= 0.0f )
|
||||
continue;
|
||||
ray lightRay;
|
||||
lightRay.start = newStart;
|
||||
lightRay.dir = (1/t) * dist;
|
||||
// calcul des ombres
|
||||
bool inShadow = false;
|
||||
for (unsigned int i = 0; i < myScene.sphTab.size(); ++i) {
|
||||
if (hitSphere(lightRay, myScene.sphTab[i], t)) {
|
||||
inShadow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!inShadow) {
|
||||
// lambert
|
||||
float lambert = (lightRay.dir * n) * coef;
|
||||
red += lambert * current.red * currentMat.red;
|
||||
green += lambert * current.green * currentMat.green;
|
||||
blue += lambert * current.blue * currentMat.blue;
|
||||
}
|
||||
}
|
||||
|
||||
// on itére sur la prochaine reflexion
|
||||
coef *= currentMat.reflection;
|
||||
float reflet = 2.0f * (viewRay.dir * n);
|
||||
viewRay.start = newStart;
|
||||
viewRay.dir = viewRay.dir - reflet * n;
|
||||
|
||||
level++;
|
||||
}
|
||||
while ((coef > 0.0f) && (level < 10));
|
||||
|
||||
imageFile.put((unsigned char)min(blue*255.0f,255.0f)).put((unsigned char)min(green*255.0f, 255.0f)).put((unsigned char)min(red*255.0f, 255.0f));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
scene myScene;
|
||||
if (!init("scene.txt", myScene))
|
||||
return -1;
|
||||
if (!draw("test.tga", myScene))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
83
src/raytracer.h
Normal file
83
src/raytracer.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
|
||||
|
||||
struct point {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
istream & operator >> ( istream &inputFile, point& p ) {
|
||||
return inputFile >> p.x >> p.y >> p.z ;
|
||||
}
|
||||
|
||||
struct vecteur {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
istream & operator >> ( istream &inputFile, vecteur& v ) {
|
||||
return inputFile >> v.x >> v.y >> v.z ;
|
||||
}
|
||||
|
||||
point operator + (const point&p, const vecteur &v){
|
||||
point p2={p.x + v.x, p.y + v.y, p.z + v.z };
|
||||
return p2;
|
||||
}
|
||||
|
||||
point operator - (const point&p, const vecteur &v){
|
||||
point p2={p.x - v.x, p.y - v.y, p.z - v.z };
|
||||
return p2;
|
||||
}
|
||||
|
||||
vecteur operator - (const point&p1, const point &p2){
|
||||
vecteur v={p1.x - p2.x, p1.y - p2.y, p1.z - p2.z };
|
||||
return v;
|
||||
}
|
||||
|
||||
vecteur operator * (float c, const vecteur &v)
|
||||
{
|
||||
vecteur v2={v.x *c, v.y * c, v.z * c };
|
||||
return v2;
|
||||
}
|
||||
|
||||
vecteur operator - (const vecteur&v1, const vecteur &v2){
|
||||
vecteur v={v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
|
||||
return v;
|
||||
}
|
||||
|
||||
float operator * (const vecteur&v1, const vecteur &v2 ) {
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
|
||||
struct material {
|
||||
float red, green, blue, reflection;
|
||||
};
|
||||
istream & operator >> ( istream &inputFile, material& mat ) {
|
||||
return inputFile >> mat.red >> mat.green >> mat.blue >> mat.reflection;
|
||||
}
|
||||
|
||||
struct sphere {
|
||||
point pos;
|
||||
float size;
|
||||
int material;
|
||||
};
|
||||
istream & operator >> ( istream &inputFile, sphere& sph ) {
|
||||
return inputFile >> sph.pos >> sph.size >> sph.material;
|
||||
}
|
||||
|
||||
struct light {
|
||||
point pos;
|
||||
float red, green, blue;
|
||||
};
|
||||
istream & operator >> ( istream &inputFile, light& lig ) {
|
||||
return inputFile >> lig.pos >> lig.red >> lig.green >> lig.blue;
|
||||
}
|
||||
|
||||
struct ray {
|
||||
point start;
|
||||
vecteur dir;
|
||||
};
|
||||
|
||||
struct scene {
|
||||
vector<material> matTab;
|
||||
vector<sphere> sphTab;
|
||||
vector<light> lgtTab;
|
||||
int sizex, sizey;
|
||||
};
|
BIN
test.tga
Normal file
BIN
test.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 900 KiB |
Reference in a new issue