bon j'ai toujours pas fini, mais je montre quand même ou j'en suis ;)
j'ai des problème avec les vector<>, je n'arrive pas à faire de pointeur sur un vector, et quand je l'utilise sans pointeur ça plombe les performances :( donc j'ai laissé la méthode bidon pour l'instant.

main.cppdispositif.hraytracer.hscene.h1606124160');">scene.hscene.cpp1606124161');">scene.cppmateriau.hlumiere.hanimation.hcamera.hcollision.hgeometrie.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

#include <iostream>
#include "time.h"

#include "dispositif.h"
#include "raytracer.h"
#include "scene.cpp"

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);

using namespace std;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;
    HWND hwnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL bQuit = FALSE;
    float theta = 0.0f;

    /* register window class */
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_OWNDC;
    wcex.lpfnWndProc = WindowProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = "GLSample";
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;


    if (!RegisterClassEx(&wcex))
        return 0;

    /* create main window */
    hwnd = CreateWindowEx(0,
                          "GLSample",
                          "Raytracer",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          800,
                          600,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    ShowWindow(hwnd, nCmdShow);

    /* enable OpenGL for the window */
    EnableOpenGL(hwnd, &hDC, &hRC);

    PerfChrono chrono;
    Ecran* lcd = new Ecran(800,600);
    scene *scene = new scene();
    lancerDeRayon* rayTracer=new lancerDeRayon(800,600);
    Animation *animation;

    Camera* macamera = scene->ajouterCamera((Position3f){0.0f, 1.0f, -10000.0f});
            macamera->cibler((Vecteur){0.0f, 0.0f, 1.0f});

    Lumiere* soleil = scene->ajouterLumiere((Position3f){ 0.0, 240.0, -1000.0});
             soleil->colorer(1.f, 1.f, 1.f);
    Lumiere* lumiere = scene->ajouterLumiere((Position3f){640.0, 240.0 ,-100.0});
             lumiere->colorer(0.3f, 0.3f, 0.3f);

    Sphere* lune = scene->ajouterSphere((Position3f){ 50.0, 290.0, 0.0});
            lune->redimensionner(40);
            lune->indexMateriau(0);
    Sphere* planeteTerre = scene->ajouterSphere((Position3f){ 350.0, 290.0, 0.0});
            planeteTerre->redimensionner(100);
            planeteTerre->indexMateriau(1);

    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */
        cout<<"Frequence de l'horloge : "<<chrono.GetFreq()<<" Hz."<<endl;
        chrono.Start();

        lune->positioner(animation->orbite(planeteTerre->Position()));
        lcd->diffuser(rayTracer->trace(scene));

        cout<<(chrono.GetDiffNs()/1000000)<<endl;
        SwapBuffers(hDC);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL(hwnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow(hwnd);

    return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_CLOSE:
            PostQuitMessage(0);
        break;

        case WM_DESTROY:
            return 0;

        case WM_KEYDOWN:
        {
            switch (wParam)
            {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                break;
            }
        }
        break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

    return 0;
}

void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd;

    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC(hwnd);

    /* set the pixel format for the DC */
    ZeroMemory(&pfd, sizeof(pfd));

    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
                  PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    iFormat = ChoosePixelFormat(*hDC, &pfd);

    SetPixelFormat(*hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    *hRC = wglCreateContext(*hDC);

    wglMakeCurrent(*hDC, *hRC);
}

void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
    ReleaseDC(hwnd, hDC);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#ifndef Dispositif_loaded
#define Dispositif_loaded

#include <gl/gl.h>

class Ecran
{
      protected:
       unsigned int largeur, hauteur;

    public:
        Ecran(int Largeur, int Hauteur):largeur(Largeur),
                                        hauteur(Hauteur)
        {
        }
        void diffuser(unsigned char*  cellulesRVB)
        {
            glDrawPixels( largeur, hauteur, GL_RGB, GL_UNSIGNED_BYTE, cellulesRVB);
        }
};
#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

#ifndef Raytracer_loaded
#define Raytracer_loaded

#include "geometrie.h"
#include "collision.h"
#include "scene.h"

class lancerDeRayon
{
    private:
        unsigned int largeur, hauteur;
        unsigned char*  cellulesRVB;
        float profondeur;
        float rouge , vert , bleu ;
        float coef ;
        int niveau ;
        Collision *collision;

    public:
        lancerDeRayon(unsigned int Largeur,unsigned int Hauteur):   largeur(Largeur),
                                                                    hauteur(Hauteur),
                                                                    cellulesRVB((unsigned char *) malloc( Largeur * Hauteur * 3 ))
        {
        }
       unsigned char* trace(scene* scene)
        {
            int z=-1;
            for (int y = 0; y <hauteur; ++y)//on parcours chaque ligne
            {
                for (int x = 0; x < largeur; ++x)//pour chaque ligne, on parcours toutes ses colonnes
                {// on traite le pixel
                    rouge = 0, vert = 0, bleu = 0;
                    coef = 1.0f;
                    niveau = 0;
                    profondeur = 20000.0f;
                    // on initialise le rayon en fonction de la position de la camera et de sa direction
                     Rayon rayonActuel = { scene->positionCamera()+ (Vecteur){ float(x), float(y), 0.f }  , scene->directionCamera()};
                     do
                     {
                        // on cherche si un objet se trouve dans le champ du rayon
                            int indexSphere= -1;
                            for (unsigned int i = 0; i < scene->nbSpheres(); ++i)
                                if (collision->sphere(rayonActuel, scene->sphereId(i), profondeur))//en cas d'intersection on definit sa distance dans "profondeur"
                                    indexSphere = i;
                            if (indexSphere == -1)// si aucun objet n'est trouver on arrete le traitement et on passe au pixel suivant
                             break;

                        //en cas d'intersection avec un objet, on va defininir un nouveau rayon partant de cet objet
                           Position3f nouveauDepart = rayonActuel.depart + profondeur * rayonActuel.direction;

                           //on calcule la normale au point d'intersection
                           Vecteur normale = calculerNormale(nouveauDepart,scene->positionSphereId(indexSphere));
                          if( normale == 0)break;

                            //on recupere le materiau
                           Materiau materiauActuel = *scene->materiauId(scene->materiauSphere(indexSphere));

                        // calcul de la valeur d'éclairement au point
                           for (unsigned int j = 0; j < scene->nbLumieres(); ++j)
                           {
                                 Lumiere lumiereActuel = *scene->lumiereId(j);
                                 Vecteur distance = lumiereActuel.Position() - nouveauDepart;
                                 if (normale * distance <= 0.0f)
                                   continue;
                                 float profondeur = sqrtf(distance * distance);
                                 if ( profondeur <= 0.0f )
                                   continue;
                                 Rayon rayonDeLumiere;
                                 rayonDeLumiere.depart = nouveauDepart;
                                 rayonDeLumiere.direction = (1/profondeur) * distance;

                                 // calcul des ombres
                                 bool ombre = false;
                                 for (unsigned int i = 0; i < scene->nbLumieres(); ++i)
                                 {
                                    if (collision->sphere(rayonDeLumiere, scene->sphereId(i), profondeur))
                                    {
                                         ombre = true;
                                         break;
                                    }
                                 }
                                 if (!ombre)
                                 {
                                    // lambert
                                    float lambert = (rayonDeLumiere.direction * normale) * coef;
                                    rouge += lambert * lumiereActuel.Rouge() * materiauActuel.rouge;
                                    vert += lambert * lumiereActuel.Vert() * materiauActuel.vert;
                                    bleu += lambert * lumiereActuel.Bleu() * materiauActuel.bleu;
                                }
                           }

                           // on itére sur la prochaine reflexion
                           coef *= materiauActuel.reflection;
                           float reflet = 2.0f * (rayonActuel.direction * normale);
                           rayonActuel.depart = nouveauDepart;
                           rayonActuel.direction = rayonActuel.direction - reflet * normale;

                           niveau++;
                     }
                    while ((coef > 0.0f) && (niveau < 10));

                    cellulesRVB[z++]=((unsigned char)min(rouge*255.0f,255.0f));
                    cellulesRVB[z++]=((unsigned char)min(vert*255.0f, 255.0f));
                    cellulesRVB[z++]=((unsigned char)min(bleu*255.0f, 255.0f));
                }
            }
            return cellulesRVB;
        }
};
#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#ifndef Scene_loaded
#define Scene_loaded

#include "materiau.h"
#include "lumiere.h"
#include "animation.h"
#include "camera.h"

class scene
{
    private:

        unsigned int nbmateriaux, nbspheres, nblumieres, nbcameras, CameraActuel;
        Materiau listeMateriaux[3];
        Sphere   listeSpheres[3];
        Lumiere  listeLumieres[3];
        Camera   listecameras[3];

    public:
        scene();
        Camera*  ajouterCamera(Position3f position);
        Sphere*  ajouterSphere(Position3f position);
        Lumiere* ajouterLumiere(Position3f position);

        //pour le raytracer
        Position3f  positionCamera()const;
        Vecteur     directionCamera()const;

        int nbMateriaux()const;
        int nbSpheres()const;
        int nbLumieres()const;

        Sphere* sphereId(unsigned int i);
        Materiau* materiauId(unsigned int i);
        Lumiere* lumiereId(unsigned int i);
        unsigned int materiauSphere(unsigned int id)const;
        Position3f positionSphereId(unsigned int id)const;
};
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

#include "scene.h"

scene::scene()
{
    nbcameras=0;
    nbmateriaux=3, nbspheres=0, nblumieres=0;
    CameraActuel=0;

    listeMateriaux[0].rouge=0.0;
    listeMateriaux[0].vert=1.0;
    listeMateriaux[0].bleu=1.0;
    listeMateriaux[0].reflection=0.5;
    listeMateriaux[1].rouge=1.0;
    listeMateriaux[1].vert=0.0;
    listeMateriaux[1].bleu=1.0;
    listeMateriaux[1].reflection=0.5;

}
Camera* scene::ajouterCamera(Position3f position)
{
    nbcameras++;
    listecameras[nbcameras-1].positioner(position);
    return &listecameras[nbcameras-1];
}
Sphere* scene::ajouterSphere(Position3f position)
{
    nbspheres++;
    listeSpheres[nbspheres-1].positioner(position);
    return &listeSpheres[nbspheres-1];
}
Lumiere* scene::ajouterLumiere(Position3f position)
{
    nblumieres++;
    listeLumieres[nblumieres-1].positioner(position);
    return &listeLumieres[nblumieres-1];
}
Position3f scene::positionCamera()const
{
    return listecameras[CameraActuel].Position();
}
Vecteur scene::directionCamera()const
{
    return listecameras[CameraActuel].direction();
}
int scene::nbMateriaux()const
{
    return nbmateriaux;
}
int scene::nbSpheres()const
{
    return nbspheres;
}
int scene::nbLumieres()const
{
    return nblumieres;
}
Sphere* scene::sphereId(unsigned int i)
{
    return &listeSpheres[i];
}
Materiau* scene::materiauId(unsigned int i)
{
    return &listeMateriaux[i];
}
Lumiere* scene::lumiereId(unsigned int i)
{
    return &listeLumieres[i];
}
unsigned int scene::materiauSphere(unsigned int id)const
{
    return listeSpheres[id].Materiau();
}
Position3f scene::positionSphereId(unsigned int id)const
{
    return  listeSpheres[id].Position();
}

1
2
3
4
5
6
7
8
9
10

#ifndef Materiau_loaded
#define Materiau_loaded

struct Materiau {
    float rouge, vert, bleu, reflection;
};

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

#ifndef Lumiere_loaded
#define Lumiere_loaded

class Lumiere
{
    private:
        Position3f position;
        float rouge, vert, bleu;

    public:
        void positioner(Position3f Position)
        {
             position = Position;
        }
        void colorer( float Rouge,float Vert,float Bleu)
        {
             rouge=Rouge;
             vert=Vert;
             bleu=Bleu;
        }
        Position3f Position()const
        {
            return position;
        }
        float Rouge()const
        {
            return rouge;
        }
        float Vert()const
        {
            return vert;
        }
        float Bleu()const
        {
            return bleu;
        }
};

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#ifndef Animation_loaded
#define Animation_loaded

class Animation
{

    public:
        Animation();
        Position3f orbite(Position3f centre)
        {
            static float alpha=0;
            alpha+=0.01;
            if(alpha>360)alpha=0;
            float distance = 200.0f;

            return (Position3f){distance * cos(alpha)+centre.x, centre.y, distance * sin(alpha)+centre.z};
        }
};

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#ifndef Camera_loaded
#define Camera_loaded

class Camera
{
    private:
        Position3f position;
        Vecteur cible;

    public:
        void positioner(Position3f Position)
        {
             position = Position;
        }
        void cibler(Vecteur Cible)
        {
             cible = Cible;
        }
        Vecteur direction()const
        {
            return cible;
        }
        Position3f Position()const
        {
            return position;
        }
};
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#ifndef Collision_loaded
#define Collision_loaded

class Collision
{
    public:
        Collision();
        bool sphere(const Rayon rayon, const Sphere* sphere, float &profondeur)
         {
           // intersection rayon/sphere

           Vecteur distance = sphere->Position() - rayon.depart;
           float B = rayon.direction * distance;
           float delta = B*B - distance * distance + sphere->Taille() * sphere->Taille();
           if (delta < 0.0f)
             return false;
           float profondeur0 = B - sqrtf(delta);
           float profondeur1 = B + sqrtf(delta);
           bool colision = false;
           if ((profondeur0 > 0.1f) && (profondeur0 < profondeur))
           {
             profondeur = profondeur0;
             colision = true;
           }
           if ((profondeur1 > 0.1f) && (profondeur1 < profondeur))
           {
             profondeur = profondeur1;
             colision = true;
           }
           return colision;
         }
};
#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

#ifndef Geometrie_loaded
#define Geometrie_loaded

#include <vector>
#include <cmath>
#include <limits>
#include <algorithm>
#define min(a,b) ((a)<(b)?(a):(b))

struct Position3f {    float x, y, z;};

struct Vecteur {float x, y, z;};

struct Rayon {
    Position3f depart;
    Vecteur direction;
};

class Sphere
{
    private:
        Position3f position;
        float taille;
        int materiau;

    public:
        void positioner(Position3f Position)
        {
             position = Position;
        }
        void  redimensionner (float Taille)
        {
             taille=Taille;
        }
        void indexMateriau(int index)
        {
            materiau=index;
        }
        Position3f Position()const
        {
            return position;
        }
        int Materiau()const
        {
            return materiau;
        }
        float  Taille()const
        {
             return taille;
        }
};

Position3f operator + (const Position3f&p, const Vecteur &v){return (Position3f){p.x + v.x, p.y + v.y, p.z + v.z };}
Position3f operator - (const Position3f&p, const Vecteur &v){return (Position3f){p.x - v.x, p.y - v.y, p.z - v.z };}

Vecteur operator - (const Position3f&p1, const Position3f &p2){return (Vecteur){p1.x - p2.x, p1.y - p2.y, p1.z - p2.z };}
Vecteur operator * (float c, const Vecteur &v){    return (Vecteur) {v.x *c, v.y * c, v.z * c };}
Vecteur operator - (const Vecteur&v1, const Vecteur &v2){return (Vecteur){v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };}
bool operator == (const Vecteur&v1, int null)
{
   if(v1.x==0 && v1.y==0 && v1.z==0)return true;
   else return false;
}

float operator * (const Vecteur&v1, const Vecteur &v2 ) {    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;}

Vecteur calculerNormale(Position3f depart,Position3f direction)
{
     Vecteur normale= depart - direction;
     float temp = normale * normale;
     if (temp == 0.0f)return (Vecteur){0,0,0};

     temp = 1.0f / sqrtf(temp);
     return temp * normale;
}
#endif