Salut à tous, dans le but d'apprendre tout en s'amusant, je propose un projet communautaire, qui est un raytracer en temps réel.
j'ai vu un exemple ici: http://www.massal.net/article/raytrace/page1.html qui démontre qu'en théorie ce n'est pas trop compliqué
Mon idée c'est de faire un rendu en temps réel+ une animation).
Je propose qu'on utilise opengl, par contre je n'y connait pas grand chose
J'ai fait 2 classes pour séparer les calculs de lancé de rayons et le mode d'affichage qu'on pourra changer.
Voilà j'ai testé avec gldrawpixels, mais si vous connaissez mieux faites signe
Que pensez-vous de l'organisation ? le but est de faire un truc simple et modulable, afin qu'on se concentre uniquement sur le lancé de rayons par la suite.
Hors ligne
je sais pas quoi dire donc bon en vrac :
pour l'organisation il faut que tu fasses quelque chose comme moi ( vu que tu dois encore avoir les sources ...)
une classe device ( écran ) avec des attributs virtuels pour les fonctions, pour que ce soit facilement portable
une classe draw ( rendu ), pas besoin d'expliquer ... et les classes math ( vector/line/... )
code en anglais
cherche un autre tuto, puis si tu trouves vraiment pas, je t'en passerai
ne pas utiliser glDrawPixel mais passer par << glBegin(GL_POINTS); glVertex2f(x,y); glEnd(); >> ou dans le cas d'une line << glBegin(GL_LINES); glVertex2f(start.x,start.y); glVertex2f(end.x,end.y); glEnd(); >>
à quoi sert ta fonction trace ? une sorte de glClear ?
tu peux utiliser mes sources si ça te fait plaisir .... ( vu que je n'ai pas encore fait ça )
il me semble qu'opengl fournit une fonction à voir ...
projet communautaire ... ouais ... ça fait longtemps que j'y pense moi aussi, mais bon flemme et j'ai pas envie de me faire passer pour un idéaliste et voir le topic sombrer dans les entrailles du forum entre "c'est quoi opengl" et "kikoulool, slt tt l'mndeuh ..."
Hors ligne
Magun :
avec des attributs virtuels pour les fonctions, pour que ce soit facilement portable
oops, je me souviens plus à quoi ça sert faut que je relise les cours...
Magun :
code en anglais
Non ! tout mais pas ça SVP, bon à part si la majorité prend le dessus mais perso je trouve que ça n'aide pas à la compréhension, enfin bon c'est un détail
Magun :
cherche un autre tuto
bein j'ai un peu cherché, et c'est celui qui m'a semblé le plus court, car le but initial est que tout le monde comprenne le procedé de raytracing, donc dit moi si tu connait d'autre tuto mais je cherche vraiment à avoir un code minimale pour commencer.
Magun :
ne pas utiliser glDrawPixel mais passer par << glBegin(GL_POINTS); glVertex2f(x,y); glEnd(); >> ou dans le cas d'une line << glBegin(GL_LINES); glVertex2f(start.x,start.y); glVertex2f(end.x,end.y); glEnd(); >>
Ok, je vais voir ça merci
Magun :
à quoi sert ta fonction trace ? une sorte de glClear ?
Mais non lol, enfin oui, mais non c'est parceque j'ai pas encore mis les calculs mais c'est la fonction qui fera le lancé de rayon
Magun :
tu peux utiliser mes sources si ça te fait plaisir .... ( vu que je n'ai pas encore fait ça )
il me semble qu'opengl fournit une fonction à voir ..."
j'ai pas très bien compris ce que tu voulait dire ?
Magun :
projet communautaire ... ouais ... ça fait longtemps que j'y pense moi aussi, mais bon flemme et j'ai pas envie de me faire passer pour un idéaliste et voir le topic sombrer dans les entrailles du forum entre "c'est quoi opengl" et "kikoulool, slt tt l'mndeuh ..."
MDR, et bien oui je te comprend, j'ai moi même hésité, mais bon.... c'est sûr qu'on peut mal percevoir les choses, on verra, plus tard je vais mieu présenter la chose, sous la forme d'un tuto-tp mais avant je voudrai m'assurer d'employer les bonnes méthodes, donc déjà merci pour ton aide
Hors ligne
j'ai pas trop le temps la vite fait 2/3 truc...
virtual permet de redéfinir les fonctions sur les classes/structures dérivées et du coup faire un appel du style mère->fonction(); qui fait une sorte de redirection automatique vers fils->fonction();
le raytracer doit être dérivé de draw, pas du device, ou le cas échéant être implanté dedans, en protected
s'il est implanté faire des fonctions style, enableRaytracerRendering, disable..., isEnabled... getRaytracer, setRaytracer ( au cas où l'utilisateur veut faire sont propre raytracer dérivé )
pour la fonction opengl je pensais à glRasterPos3f qui, si mes souvenirs sont bons, retourne une position 2d(screen) d'une position3d, ça peut aider
pour les sources je pensais que tu pouvais récupérer mes classes device et draw, et les simplifier quelque peu par exemple mais tu fais comme tu veux
Hors ligne
Magun :
j'ai pas trop le temps la vite fait 2/3 truc...
virtual permais de redefinir les fonctions sur les class/structure dériver et du coup faire un apelle du style mere->function(); qui fait une sorte de redirection automatique vers fils->function();
ok ,bon du coup j'en profite pour approfondir, je vais remanier tout ça
Magun :
le raytracer doit être dériver de draw, pas du device, où le cas échéant être implenter dedans, en protected
s'il est implenter faire des fonctions style, enableRaytracerRendering, disable..., isEnabled... getRaytracer, setRaytracer ( au cas ou l'utilisateur veut faire sont propre raytracer dériver )
tu veux dire déclarer l'"Ecran" dans le "Lancerderayon" ou l'inverse ?
Magun :
pour la fonction opengl je penssais a glRasterPos3f, si mais souvenir sont bon retourne une position 2d(screen) d'une position3d, sa peut aider
non je pense pas qu'on en ai besoin, mais c'est toujours bon à savoir
Magun :
pour les source je penssais que tu pouvais récupéré mais class device et draw, et de les simplifier quelque peut par exemple mais tu fait comme tu veut
Oui j'y jeterai un oeil
Hors ligne
non déclarer le raytracer dans la classe de rendu, pas celui de l'écran
Hors ligne
ha bein oui qu'est ce que je raconte moi
Je comptais faire simple mais en y réfléchissant un peu ça va pas le faire, dans l'exemple tout le code de raytracing est dans une même fonction, mais c'est pas flexible, y a la scène, les lumières, les matériels...... En fait je crois que c'est l'occasion de faire 2 tp en 1, raytracer+ l'organisation en C++, je pense que ça peut être que bénéfique pour les membres comme moi qui sont pas trop branchés POO.
Donc je sais pas trop comment procéder, je sais qu'irrlicht utilise des Interfaces comme tu le disais plus haut Magun, mais j'ai peur que ça alourdisse le code ?, enfin je sais pas combien ça va faire de fichiers tout ça, dis moi ce que t'en pense, mais il faudrait peut-être faire aussi des classes: scene, Lumiere, Mesh.... afin que le moteur soit aisément améliorable, sans pour autant qu'il y ait trop de fichiers, j'ai d'ailleurs fait que des headers justement pour alléger le nombre de fichiers.
Comment verrais-tu la chose ?
Hors ligne
ah ah ça parle architecture j'adore
bon perso je ferais le truc en une dizaine de fichiers, forcément dès que l'on commence à songer à faire un moteur ça devient un peu volumineux avec pas grand chose
pour que ça reste organisé, il faut forcément des dossiers
bon en restant dans un truc modeste ... ( tu fais comme tu veux pour les noms des fichiers, je fai ça vite fait )
device/device.* device/device_sdl.* // dérivé du device device/device_glut.* // dérivé du device device/device_win.* // dérivé du device device/device_w11.* // dérivé du device node/scene.* // implémente un array<node*> node/light.* // dérivé de node node/node.* // base pour les nodes dérivés, ne contient que les données superflues ( texture, mesh, ... ) node/real.* // node de rendu de mesh ( standard) node/skybox.* // dérivé de node node/geometry.* // classe qui va générer les meshs node/mesh.h // juste une structure avec des float* ( vertices, indices, TCoord et ... et normales ) render/draw.* // rendu graphique des éléments ( utilisé par les nodes ) render/raytracer.* // implémenté dans draw, au final je pense que c'est le mieux redner/texture.* // chargement intégré pour pas se casser la tête ( tga c'est pas compliqué à charger ) math/vector2d.h math/vector3d.h math/line2d.h math/line3d.h // utilisé par le raytracer math/matrix4.h // utilisé dans le device pour modifier la matrice de perspective, enfin sauf si tu veux utiliser les fonctions standard, donc optionnel je pense math/array.h // pas indispensable, mais dans la "scène" il te faudra utiliser des std::vector et pas des std::array, trop lent
vite fait, je pense que c'est tout, mais tu verras vite fait que tu voudras rajouter des fonctionnalités ...
ps: ne faire que des headesr n'est pas la solution je dirais même que c'est super emmerdant après, à chaque modif ça va recompiler chaque fichier où ton header est inclus, directement ou non
edit: oublié la spec de real
Dernière modification par Magun (29-08-2010 15:34:54)
Hors ligne
ok, ce soir je vais faire des essais d'organisation, la principale difficulté pour moi c'est de faire communiquer les classes entre elles proprement. je manque cruellement d'experience.
Sinon j'ai fait vite fait une animation genre la lune en orbite autour de la terre, je pense que c'est l'idéal pour commencer, mais en vue orthographique c'est pas terrible; et je suis à 15% du cpu, donc je vois déjà 2 améliorations futur, qui sont la vue en perspective et le multthreading. mais d'abord faut que je fasse l'organisation
Hors ligne
piouf, ça me prend plus de temps que prevu, j'espère présenter un essai cette nuit, j'ai bientot fini tout l'aspect "moteur" par contre pour le "device" j'ai pas encore commencé, en fait j'aurais besoin que tu me conseille comment faire des main() differents ? pour linux et tout, car j'ai fait "créer un nouveau projet opengl" avec codeblock et il me sort ça
Donc je sais pas comment procédé ?
Hors ligne
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.
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 |
Hors ligne
bon commençons, le main .. oui c'est vrai c'est déjà un soucis pour les systèmes portables, mais il suffit d'utiliser #if defined ...
en règle générale on utilise ça ... avec des variantes mais c'est le même principe
après j'ai vu que tu initialises la fenêtre win32 dans la main, bon je pense que ce sera que temporaire mais go -> device spécifique ... enfin moi je vois ça comme ça
géométrie c'est pas trop mal, mais j'aurais pas tout à fait fait comme cela ... je suis pas sûr que t'aies bien compris, c'est peur-être ta vision des choses je n'ai rien contre
pour le reste rien à dire mais
- 1: pourquoi il n'existe pas de Node ? qui relie Sphere, Lumiere, Camera ? tu n'aurais donc plus besoin de faire un array pour chaque type ....
example:
resulta ...
A return: 1
donc si tu fais dériver Sphère, Lumière, Camera d'une classe plus "haute"
tu n'as besoin que d'un seul array pour stocker plusieurs types de "node" différents ...
ps 1: pas très pratique de coder sur le forum
ps 2: je pense que tu as encore quelque difficultés avec le poo, c'est pas facile pour beaucoup de personnes, mais qu'est-ce que c'est bien
donc si tu veux je peux te faire une base de ma base de "moteur", du moins pour le device et l'architecture ? mais ne tard pas trop, je reprends les cours jeudi et je serai interne toute la semaine
Hors ligne
Magun :
après j'ai vue que tu initialise la fenètre win32 dans la main, bon je pensse que se sera que temporaire mais go -> device spéciafique ... enfin moi je voie sa comme ça
oui je vais le faire, je n'ai jamais utilisé directement les fenêtres d'un os, je suis toujours passé par des lib, donc faut que je trouve le temps de me documenter et après je rangerai tous ça
Magun :
geometri c'est pas trop mal, mais j'aurais pas tout a fait, fait comme cela ... je suis pas sur que t'est bien comprit, c'est peur-être ta vision des chose je n'est rien contre
non c'est pas ma vision des choses(à vrai dire j'ai justement du mal à m'en faire une), j'ai juste fait au plus direct, et au plus simple, mais c'est clair que ça sera à faire par la suite, il faut dire aussi que je ne suis pas expérimenté en 3d non plus lol, donc il y a des truc que je ne comprends pas encore, là par exemple pour ajouter une texture au raytracer, je n'ai pour l'instant aucune idée de comment procéder, donc j'apprends au fur et à mesure aussi
Magun :
pour le reste rien a dire mais
- 1: pourquoi il n'existe pas de Node ? qui relie Sphere, Lumiere, Camera ? tu n'aurais donc plus beusoin de faire un array pour chaque type ....
j'ai envie de dire +1, faut que je fasse ça....
Magun :
ps 2: je pensse que tu a encore quelque dificulter avec le poo, c'est pas facil pour beaucoup de personne, mais quesque c'est bien
+1, c'est pas facile mais c'est pas difficile non plus, je dirai que ça peut être complexe
Magun :
donc si tu veut je peut te faire une base de ma base de "moteur", du moin pour le device et l'architecture ? mais ne tard pas trop, je reprend les cours jeudi et je serait interne toute la semaine
bein je veux bien, tout aide est la bienvenue , mais pas si ça te prend trop de temps, faut que tu profites des vacances sinon t'as pas internet à ton internât ?
en tout cas merci pour les critiques, je peux pas tout corriger d'un coup(need doc), mais je prends bien en compte tout ce que tu dis
Hors ligne
bon alors pour les textures c'est pas très compliqué opengl fait quasiment tout
ça se fait en deux étapes:
allocation mémoire en vram et création d'une id pour la texture
utilisation de la texture appelant l'id ...
bon je suppose que tu sais déjà comme est les principe d'une texture ? enfin ... c'est pas compliquer tu crées un tableau "1D", où tu stockes les données, de dimension width*height+1
pour se localiser, la position = x+height*y plus ou moins, faut prendre aussi en compte que tu utilises 3 ou 4 "channel" on va dire le format ( 8, 16, 24, 32 respectivement, noir/blanc, noir/blanc/alpha, rgb oou yuv, argb ou rgba) donc ton tableau est égal à width*height*(format/8)+1, c'est toujours pareil pour se localiser (x+hieght*y)*(format/8), et pour retrouver les couleurs tu fais juste position+x ou x < format/8, pas trop compliqué jusque là ?
c'est juste la partie software ( chargement ) après pour passer à opengl:
suppression de la texture:
et l'utilisation:
le problème c'est qu'il faut spécifier quel endroit de la texture sera "plaqué" sur tel polygone, pour ça on utilise << glTexCoord3i(0,1,0); >> ou 0 c'est le bord supérieur haut ou gauche et 1 le bord inférieur ou droit
c'est bon j'y suis pas aller trop fort jusque là ?
sinon avec un peu de chance je ne suis pas dans le même internat que celui de l'an dernier où je ne captais pas la wifi, mais la rumeur court que le pions qui avaient la wifi la désactivaient ... mais t'inquiète c'est le premier truc que je teste
ps: désolé pour le "-1" je voulais faire une énumération mais je suis partie dans un discours
oh et ça ne fait que 3 semaines que je bosse sous opengl donc je ne connais pas tout non plus ... (depuis le sleekthink)
edit: je poste le code demain ... et je ferai un effort, les sources en "français" + doc/commentaire ...
Dernière modification par Magun (01-09-2010 00:00:58)
Hors ligne
bon voilà le minimal, sans les fonctions de rendu/raytracing et autre, j'ai pas euh le temps, et puis ça n'a plus d'intérêt si je fais tout
http://www.mediafire.com/?1fb1zqyyv520c1q
mais pour l'architecture ça devrait déjà t'aider je pense, ceci dit ... comme tu le sais je suis sous linux, donc ... à toi de mettre les options de compilation
of et y a des commentaires un peut partout ... si ça peut t'aider ... j'en sais rien ..., tu as juste besoin de rajouter sdl
Hors ligne
Merci pour l'exemple de hiérarchie je devrais arriver à faire quelque chose de "propre" d'ici quelque jours.
Sinon pour les textures, j'suis un fou moi j'avais pas vu que c'était expliqué dans le tuto http://www.massal.net/article/raytrace/page3.html , en fait le tuto est en 6 parties, et il décrit les principales notions à savoir, mais n'est pas optimisé pour du temps réel. donc ça promet tout ça
ps: tu reviens vendredi ?
Hors ligne
je me souvient que tu parlais de multy-threading ? je te préviens a l'avence tu va avoir des soucis
opengl n'est pas encore "totatlement orienter thread", ou plutot il ne les pas du tout, seulement en passant par opencl, qui nécéssite une carte graphique ou cpu(avec un fpu rapide+sse3 ou sse4) récent donc ...
et des driver a jour ( nvidia 186.xx il me semble, ou ati catalyst 10.7 + ati stream )
sinon changement de programme la rentré séfectue vendredie, histoire de faire chier le peuple ...
140 borne dans la jounée ... pas très écolo tout sa ... et biensur pas de bus
Hors ligne
Magun :
opengl n'est pas encore "totatlement orienter thread", ou plutot il ne les pas du tout
Mais en fait si j'utilise opengl, c'est juste pour afficher le tableau de pixels, rien de plus donc ça n'empeche pas de paralléliser les lancés de rayons qui consomment énormément de ressources
Hors ligne
Coucou,
je suis en train de faire comme tu dit Magun mais je rencontre de serieux problème de performances, cela ne viens pas de ton code puisque j'ai regardé dans irrlicht est c'est là même.
outre le problème de lenteur des <vector>, je rencontre maintenant un problème de lenteur sur la structure vecteur3, voici comment j'ai procédé:
Le problème se situe dans les 'return' des operator qui sont beaucoup plus lent(+10ms par frame) que ça:
Donc je sais pas comment procéder pour faire un return de ce type mais avec l'organisation précédente ?, en tout cas ce qui est sûre c'est que le code d'irrlicht à encore une bonne marge d'optimisation.
EDIT: c'est bon j'ai trouvé le problème venait du constructeur qui m'empêchais de faire ce type de retour, voici le code optimisé:
C'est un peu moins propre mais beaucoup plus performant !
Hors ligne
bon je pense qu'il est temps que je jette un coup d'oeil à ce tuto cela ?
histoire de voir l'avancement ou ce qui pourrait être changé/amélioré ...
Hors ligne
attends tout à l'heure je te montre où j'en suis..... j'ai toujours pas fini mais j'ai beaucoup gagné en performances....
edit: voilà il y a des fichiers où c'est encore le bordel notamment win.h c'est le bronx lol.
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 | #include "dispositif.h"//device pour les intimes #include "rendu.cpp"//raytracer #include "scene.cpp" #include "animation.h" int main() { //______________________________________MOTEUR Animation *animation; C_Ecran* ecran = new C_Ecran(800,600); C_Rendu* rendu = new C_Rendu(800,600); C_Scene* scene = new C_Scene(); //__________________________________________________________________________SCENE C_Camera* macamera = scene->ajouterCamera(Vecteur(0.0, 1.0, -10000.0)); macamera->cibler(Vecteur(0.0, 0.0, 1.0)); C_Lumiere* soleil = scene->ajouterLumiere(Vecteur( 0.0, 240.0, -1000.0)); soleil->colorer(1.0, 1.0, 1.0); C_Lumiere* lumiere = scene->ajouterLumiere(Vecteur(640.0, 240.0 ,-100.0)); lumiere->colorer(0.3, 0.3, 0.3); I_Forme* lune=new C_Sphere(Vecteur( 50.0, 290.0, 0.0)); lune->redimensionner(40); lune->definirMateriau(0); scene->ajouterForme(lune); I_Forme* planeteTerre=new C_Sphere(Vecteur( 350.0, 290.0, 0.0)); planeteTerre->redimensionner(100); planeteTerre->definirMateriau(1); scene->ajouterForme(planeteTerre); //__________________________________________________________________BOUCLE PRINCIPALE while (!quitter()) { lune->positioner(animation->orbite(planeteTerre->Position())); ecran->diffuser(rendu->lancerDeRayons(scene->parametres())); } //____________________AU REVOIR delete lune; delete planeteTerre; delete scene; delete rendu; delete ecran; return 0; } |
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 | #ifndef Scene_loaded #include "lumiere.h" #include "camera.h" #include "sphere.h" struct S_Scene//*********************************************************** {//structure contenant les paramètres de la scene à envoyer au raytracer Materiau listeMateriaux[3]; I_Forme* listeFormes[3]; C_Lumiere listeLumieres[3]; C_Camera* cameraActuel; int nbformes, nblumieres; S_Scene(): nbformes(0), nblumieres(0){} };//*********************************************************************** class C_Scene { private://** *************************** int nbcameras, idCameraActuel; C_Camera listeCameras[3]; S_Scene* parametresScene; public://***** ********************************************* C_Scene(); C_Camera* ajouterCamera(vecteur3f position); void ajouterForme(I_Forme* forme); C_Lumiere* ajouterLumiere(vecteur3f position); S_Scene& parametres()const {return *parametresScene;} ~C_Scene() {delete parametresScene;} }; #define Scene_loaded #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 | #include "scene.h" //______________________________________________________________________________________INIT C_Scene::C_Scene():nbcameras(0),idCameraActuel(0) { parametresScene=new S_Scene; parametresScene->listeMateriaux[0].rouge=0.0; parametresScene->listeMateriaux[0].vert=1.0; parametresScene->listeMateriaux[0].bleu=1.0; parametresScene->listeMateriaux[0].reflection=0.0f; parametresScene-> listeMateriaux[1].rouge=1.0; parametresScene->listeMateriaux[1].vert=0.0; parametresScene->listeMateriaux[1].bleu=1.0; parametresScene-> listeMateriaux[1].reflection=1.0; }//_____________________________________________________________________________________AJOUTER_CAMERA C_Camera* C_Scene::ajouterCamera(vecteur3f position) { nbcameras++; listeCameras[idCameraActuel].positioner(position); parametresScene->cameraActuel=&listeCameras[idCameraActuel]; return &listeCameras[idCameraActuel]; }//_____________________________________________________________________________________AJOUTER_FORME void C_Scene::ajouterForme(I_Forme* forme) { parametresScene->listeFormes[++parametresScene->nbformes-1]=forme; }//_____________________________________________________________________________________AJOUTER_LUMIÈRE C_Lumiere* C_Scene::ajouterLumiere(vecteur3f position) { parametresScene->listeLumieres[++parametresScene->nblumieres-1].positioner(position); return ¶metresScene->listeLumieres[parametresScene->nblumieres-1]; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #ifndef Noeud_loaded #include "math.h" class I_Noeud //Interface pour manipuler cameras, lumieres et formes dans la scene { protected: vecteur3f position; public: virtual void positioner(const vecteur3f& Position){this->position = Position;} virtual vecteur3f Position()const{return position;} }; #define Noeud_loaded #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #ifndef Camera_loaded #include "noeud.h" class C_Camera : public I_Noeud { private: vecteur3f cible; public: void cibler(const vecteur3f Cible){this->cible = Cible;} vecteur3f direction()const{return cible;} }; #define Camera_loaded #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #ifndef Lumiere_loaded #include "noeud.h" class C_Lumiere : public I_Noeud { private: float rouge, vert, bleu; public: void colorer(const float Rouge,const float Vert,const float Bleu) { this->rouge=Rouge; this->vert=Vert; this->bleu=Bleu; } float Rouge()const {return rouge;} float Vert()const {return vert; } float Bleu()const {return bleu; } }; #define Lumiere_loaded #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 | #ifndef Forme_loaded #include "noeud.h" class I_Forme : public I_Noeud //Interface pour manipuler les sphères, cubes et autres formes géometriques { protected: float taille; int materiau; public: I_Forme(){} //************* ********************************************************************** virtual void redimensionner (const float Taille ) {this->taille = Taille; } virtual void definirMateriau(const int index ) {this->materiau = index; } //************* *************************************************** virtual bool collision(const Rayon &rayon, float &profondeur)=0; //************* ********************************** virtual int Materiau()const {return materiau;} virtual float Taille ()const {return taille; } //************* ************ virtual ~I_Forme(){} }; #define Forme_loaded #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 Sphere_loaded #include "forme.h" class C_Sphere : public I_Forme { public: C_Sphere(vecteur3f Position) { this->position=Position; } bool collision(const Rayon &rayon, float &profondeur) { // intersection rayon/sphere vecteur3f distance = this->position - rayon.depart; float B = rayon.direction * distance; float delta = B*B - distance * distance + this->taille * this->taille; if (delta < 0.0f)return false; float profondeur0 = B - sqrtf(delta); bool colision = false; if ((profondeur0 > 0.1f) && (profondeur0 < profondeur)) { profondeur = profondeur0; colision = true; } float profondeur1 = B + sqrtf(delta); if ((profondeur1 > 0.1f) && (profondeur1 < profondeur)) { profondeur = profondeur1; colision = true; } return colision; } ~C_Sphere() { } }; #define Sphere_loaded #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 | #ifndef Rendu_loaded #include <iostream> #include "math.h" #include "scene.h" #include "time.h" class C_Rendu { private: PerfChrono chrono; unsigned char* pixelsRVB; int largeur, hauteur, niveau; float rouge, vert, bleu, coef, profondeur; public: C_Rendu(int Largeur, int Hauteur):pixelsRVB((unsigned char *) malloc( Largeur * Hauteur * 3 )), largeur(Largeur), hauteur(Hauteur) { } unsigned char* lancerDeRayons(const S_Scene& scene); ~C_Rendu(){delete pixelsRVB;} }; #define Rendu_loaded #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 | #include "rendu.h" unsigned char* C_Rendu::lancerDeRayons(const S_Scene& scene) { std::cout<<"Frequence de l'horloge : "<<chrono.GetFreq()<<" Hz."<<std::endl; chrono.Start(); int z=-1; vecteur3f positionCamera =scene.cameraActuel->Position(); vecteur3f directionCamera=scene.cameraActuel->direction(); for (int y = 0; y <hauteur; ++y)//boucle de parcours des lignes { for (int x = 0; x < largeur; ++x)//boucle de parcours des pixels { 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 = { positionCamera + Vecteur( float(x), float(y), 0.f ) , directionCamera}; do//boucle de reflexion { //Recherche de formes se trouvant dans le champ du rayon int indexForme= -1; for (int i = 0; i < scene.nbformes; ++i) if (scene.listeFormes[i]->collision(rayonActuel, profondeur))//en cas d'intersection on definit sa distance dans "profondeur" indexForme = i; if (indexForme == -1) break; //en cas d'intersection avec un objet, on va defininir un nouveau rayon partant de cet objet vecteur3f nouveauDepart = rayonActuel.depart + rayonActuel.direction * profondeur; //on calcule la normale au point d'intersection vecteur3f normale = nouveauDepart.calculerNormale(scene.listeFormes[indexForme]->Position()); if( normale == 0)break; //on recupere le materiau Materiau materiauActuel = scene.listeMateriaux[scene.listeFormes[indexForme]->Materiau()]; //calcul de la valeur d'éclairement au point for (int j = 0; j < scene.nblumieres; ++j) { C_Lumiere lumiereActuel = scene.listeLumieres[j]; vecteur3f 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 = distance * (1/profondeur) ; //calcul des ombres bool ombre = false; for (int i = 0; i < scene.nblumieres; ++i) { if (scene.listeFormes[i]->collision(rayonDeLumiere, 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 - normale * reflet; niveau++; } while ((coef > 0.0f) && (niveau < 10)); pixelsRVB[z++]=(unsigned char)std::min(rouge*255.0f, 255.0f); pixelsRVB[z++]=(unsigned char)std::min(vert *255.0f, 255.0f); pixelsRVB[z++]=(unsigned char)std::min(bleu *255.0f, 255.0f); } } std::cout<<(chrono.GetDiffNs()/1000000)<<std::endl; return pixelsRVB; } |
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 | #ifndef Math_loaded #include <vector> #include <cmath> #include <limits> #include <algorithm> template<typename T> struct vecteur3//**************************************************************************VECTEUR3 { T X, Y, Z; vecteur3<T> operator + (const vecteur3<T>& v2)const {return (vecteur3<T>){X +v2.X, Y +v2.Y, Z +v2.Z};} vecteur3<T> operator - (const vecteur3<T>& v2)const {return (vecteur3<T>){X -v2.X, Y -v2.Y, Z -v2.Z};} vecteur3<T> operator * (const float& c) const {return (vecteur3<T>){X *c, Y *c, Z *c };} float operator * ( vecteur3<T>& v2) const {return X *v2.X +Y *v2.Y +Z *v2.Z ;} bool operator ==(const int& nb) const {return (X==nb &&Y==nb &&Z==nb ) ;} vecteur3<T> calculerNormale( vecteur3<T> direction) { vecteur3<T> normale= *this - direction; float temp = normale * normale; if (temp == 0.0f)return (vecteur3<T>){0,0,0}; return normale * (1.0f / sqrtf(temp)) ; } };//************************************************************************************************************* typedef vecteur3<float> vecteur3f; vecteur3f Vecteur(float x, float y, float z){return (vecteur3f){x,y,z};} struct Rayon{//**************************************************************************************************RAYON vecteur3f depart, direction; };//************************************************************************************************************* struct Materiau {//**********************************************************************************************MATERIAU float rouge, vert, bleu, reflection; }; #define Math_loaded #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 | #ifndef Dispositif_loaded #include <gl/gl.h> #if (defined WIN32 || defined WIN64) #include "win.h" #else #include "linux.h" #endif class C_Ecran { protected: unsigned int largeur, hauteur; public: C_Ecran(unsigned int Largeur,unsigned int Hauteur): largeur(Largeur), hauteur(Hauteur) { } void diffuser(unsigned char* cellulesRVB)const { glDrawPixels( largeur, hauteur, GL_RGB, GL_UNSIGNED_BYTE, cellulesRVB); swap(); } }; #define Dispositif_loaded #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 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 | #include <windows.h> #define main Moteur LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); void EnableOpenGL(HWND hwnd, HDC*, HGLRC*); void DisableOpenGL(HWND, HDC, HGLRC); using namespace std; MSG msg; HDC hDC; int Moteur(); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; HWND hwnd; HGLRC hRC; /* 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 = "Frequence de l'horloge : "; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);; if (!RegisterClassEx(&wcex)) return 0; /* create main window */ hwnd = CreateWindowEx(0, " Hz.", "GLSample", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); /* enable OpenGL for the window */ EnableOpenGL(hwnd, &hDC, &hRC); /* fake main*/ Moteur(); /* shutdown OpenGL */ DisableOpenGL(hwnd, hDC, hRC); /* destroy the window explicitly */ DestroyWindow(hwnd); return msg.wParam; } bool quitter() { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { /* handle or dispatch messages */ if (msg.message == WM_QUIT) { return true; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } return false; } void swap() { SwapBuffers(hDC); } 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 | #ifndef Animation_loaded class Animation { public: Animation(); vecteur3f orbite(vecteur3f centre)const { static float alpha=0; alpha+=0.01; if(alpha>360)alpha=0; float distance = 200.0f; return Vecteur(distance * cos(alpha)+centre.X, centre.Y, distance * sin(alpha)+centre.Z); } }; #define Animation_loaded #endif |
Hors ligne
c'est pas mal, je suis pas mécontent, je vois que mon exemple a servi un peu
quelques remarques si ça peut t'aider plus tard
this-> pas obligatoire en règle générale sauf rare cas ( exemple la classe a une variable Blabla et que la fonction a un paramètre qui s'appelle aussi Blabla, mais ici rouge et Rouge il n'y a pas de soucis )
tu n'es pas obligé de spécifier un nom de variable dans les déclarations de variable ... mais c'est juste histoire de coder plus vite
dans materiaux tu pourrais utiliser un vecteur3<unsigned char> pour les couleurs, mais bon c'est un détail
fais attention à <<#define main Moteur>> je ne sais pas si c'est voulu mais concrètement le define va remplacer tout les main par Moteur, où qu'il soit, surtout qu'il est dans un headler sa implique que les fichiers qui l'incluent sont affectés ...
et puis peut-être pas assez de guard
question: tu as un rendu graphique ? pour l'histoire des vecteur3, désolé j'étais pas là, mais ça a eu peut être du bon ? ^^
Hors ligne
C'est génial tes onglets avec ton code !! tu files les balises BB stp ?
Et sinon c'est ça que t'appelles du bordel ?!
Attends de recevoir mon mail
Hors ligne
TUpac :
C'est génial tes onglets avec ton code !! tu file les balises BB stp ?
C'est ecrit dans le fichier d'aide (help.php)
@Magun, ouai t'a vu j'ai honoré ton exemple et encore il a pas mal de truc que j'ai pas encore mis, les <vector> par exemple, me font perdre 20 ms par frame étant donnée les millions d'accés par seconde, je songe donc à faire une copie dans un tableau à taille fixe avant f'envoyer au raytraceur etc etc...
le this je les mis juste pour la lisibilité, c'est clair que c'est pas obligé,
pour le define moteur, ouai t'a raison faut pas le placé n'importe ou, il faudrait mieu l'appelé MainWIN par exemple, mais avous que l'astuce du fake main est pas mal
sinon c'est quoi c'est guard ? je connais pas.
you said: tu a un rendue graphique?
pourquoi toi non ? ou est le problème ? ha oui faut faire linux.h maintenant.....
Hors ligne
guard:
surtout utilisé pour éviter les inclusions multiples
pour le rendu, d'une part oui linux, d'autre part, créer un projet, faire les fichier, recopier les codes, c'est long ...
Hors ligne