Raytracer en temps réel et en assembleur

Description

Bonjour à tous !
Je viens de finir mon second RayTracer (du moins disons qu'il affiche quelque chose de potable) et je me suis dit que ça intéresserait peut-être certains d'entre vous d'avoir le code.
Donc voici une petite démonstration sans prétention, ainsi que les portions de code chargé de l'affichage 3D.
Sur ce, je retourne préparer la version 0.22, avec des effets d'éclairage cette fois-ci.

Vous pouvez déplacer la caméra avec les flèches. Appuyez sur F1 pour afficher la liste des commandes ( il y a aussi pas mal d'effet visuel qui n'ont rien avoir avec le RayTracing, appuyez sur la touche "\" pour voir...).

La compilation est prévue pour se faire sous Visual Studio C++ 2008, d'où le listing principal en C++ alors que la librairie est en ASM.

Le RayTracing vaincra ! A bas la Projection !

Source / Exemple :


#include <windows.h>
#include "Hydrargyrum.h"

#pragma comment(linker, "/entry:Main")

void __stdcall Procedure3D(HWND hdlg, UINT mssg, WPARAM wParam, LPARAM lParam);

DWORD ValeurContraste=256;
DWORD ValeurLuminance=256;
DWORD ValeurColoration=Coloration_Complete;
DWORD ValeurFiltre=0;
DWORD ValeurXincremental=0;
DWORD StatutSession=1;
DWORD AideON=0;

HgHandle ImageAide=0;
HgHandle PoliceComicSansMS=0;

HgHandle ObjetTestPave1;
HgHandle ObjetTestPave2;
HgHandle ObjetTestPave3;
HgHandle ObjetTestSphere1;
DWORD	 AngleRotationObjetTest;

struct HgCamera Camera1;

int Main(int argc, char* argv[])
{ 

MSG BoiteMsg;

HgCreerAffichage(Procedure3D,Mode_PleinEcran,1024,768,Couleur_32bits); //redimensionne

ImageAide = HgChargerImage("Images/Aide.bmp");											//charge l'image d'aide
PoliceComicSansMS = HgChargerPolice("Images/ComicSansMS.bmp","Images/ComicSansMS.txt"); //charge une police de texte

Camera1.X=0;
Camera1.Y=0;
Camera1.Z=0;
Camera1.Recul=500;
Camera1.RotationX=0;
Camera1.RotationY=0;
Camera1.RotationZ=0;
ObjetTestPave1 = HgChargerObjet(0,0,0,600,20,250,250,0x7f7fff,0x007fff,0x7f7fbf,0x0000ff,0x00ffff,0x00ff00);
ObjetTestPave2 = HgChargerObjet(0,0,0,600,50,50,250,0xa0a0a0,0xc0c0c0,0xd0d0d0,0xc0c0c0,0xd0d0d0,0xa0a0a0);
ObjetTestPave3 = HgChargerObjet(0,0,0,600,200,200,200,0xf02020,0xf04040,0xf06060,0xf08080,0xf0a0a0,0xf0c0c0);
ObjetTestSphere1 = HgChargerObjet(1,0,0,600,100,0,0,0x6f6f6f,0,0,0,0,0);

 StatutSession=1;
 while (StatutSession == 1)
 {
	GetMessage(&BoiteMsg,0,0,0);
	DispatchMessage(&BoiteMsg);
 }

 ExitProcess(0);

}

void Procedure3D(HWND hdlg, UINT mssg, WPARAM wParam, LPARAM lParam)
{	long FPS;
	char TamponFPS[10];	//pour l'affichage du nombre d'images par secondes

	switch(mssg) 
	{
    case WM_KEYDOWN:
		switch(wParam) 
		{
        case VK_NUMPAD9: // touche plus
		ValeurContraste = ValeurContraste + 20;
		HgModifierContraste(ValeurContraste);
		return;

		case VK_NUMPAD6: // touche moins
		ValeurContraste = ValeurContraste - 20;
		HgModifierContraste(ValeurContraste);
		return;

		case VK_NUMPAD8: // touche plus
		ValeurLuminance = ValeurLuminance + 20;
		HgModifierLuminance(ValeurLuminance);
		return;

		case VK_NUMPAD5: // touche moins
		ValeurLuminance = ValeurLuminance - 20;
		HgModifierLuminance(ValeurLuminance);
		return;

		case VK_NUMPAD7: // touche rouge
		ValeurColoration = ValeurColoration ^  Rouge;
		HgModifierColoration(ValeurColoration);
		return;

		case VK_NUMPAD4: // touche vert
		ValeurColoration = ValeurColoration ^  Vert;
		HgModifierColoration(ValeurColoration);
		return;

		case VK_NUMPAD1: // touche bleu
		ValeurColoration = ValeurColoration ^  Bleu;
		HgModifierColoration(ValeurColoration);
		return;

		case VK_NUMPAD0: // touche noir et blanc
		ValeurColoration =  Coloration_Noir_Blanc;
		HgModifierColoration(ValeurColoration);
		return;

		case VK_ESCAPE:	// touche echap
		HgTerminerAffichage();
		ExitProcess(0);
		return;

		case VK_RETURN:	// touche entrée
		HgTerminerAffichage();
		ExitProcess(0);
		return;

		case VK_F12: //touche F12 - Capture écran
		HgEnregistrerAffichage();
		return;

		case VK_F1: //touche F1 - Aide
		AideON = AideON ^ 1;
		return;

		case 0x31:		// touche 1
		ValeurFiltre = ValeurFiltre ^ Filtre_Luminance_Contraste;	//filtre 1 : LC
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x32:		// touche 2
		ValeurFiltre = ValeurFiltre ^ Filtre_Dilatation;	//filtre 2 : Dilatation
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x33:		// touche 3
		ValeurFiltre = ValeurFiltre ^ Filtre_Erosion;	//filtre 3 : Erosion
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x34:		// touche 4
		ValeurFiltre = ValeurFiltre ^ Filtre_Contour;	//filtre 4 : Contour
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x35:		// touche 5
		ValeurFiltre = ValeurFiltre ^ Filtre_Coloration;	//filtre 5 : Coloration
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x36:		// touche 6
		ValeurFiltre = ValeurFiltre ^ Filtre_Gaussien;	//filtre 6 : Gaussien
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x37:		// touche 7
		ValeurFiltre = ValeurFiltre ^ Filtre_Gaussien_Pondere;	//filtre 7 : Gaussien Pondéré
		HgModifierFiltre(ValeurFiltre);
		return;

		case 0x38:		// touche 8
		ValeurFiltre = ValeurFiltre ^ Filtre_Mouvement;	//filtre 8 : Motion Blur
		HgModifierFiltre(ValeurFiltre);
		return;

		case VK_BACK: // touche retour arriere
		HgModifierContraste(256);
		HgModifierLuminance(256);
		HgModifierColoration(Coloration_Complete);
		ValeurContraste=256;
		ValeurLuminance=256;
		ValeurFiltre=0;
		HgModifierFiltre(Filtre_Inactif);
		return;

		case VK_RIGHT:	//flèche droite
		Camera1.X = Camera1.X + 10;
		return;

		case VK_LEFT:	//flèche gauche
		Camera1.X = Camera1.X - 10;
		return;

		case VK_UP:		//flèche haut
		Camera1.Z = Camera1.Z + 10;
		return;

		case VK_DOWN:	//flèche bas
		Camera1.Z = Camera1.Z - 10;
		return;

		case 0x21:	//flèche début
		Camera1.Y = Camera1.Y + 10;
		return;

		case 0x22:	//flèche fin
		Camera1.Y = Camera1.Y - 10;
		return;

		}

		DefWindowProc(hdlg,mssg,wParam,lParam);
		return;
	
	case WM_PAINT:

	HgEffacerAffichage();
	HgAfficherTexte(200,10,PoliceComicSansMS,"Demonstration 3D : Lancer de Rayon",0,0xc0ffff);
	HgAfficherTexte(10,710,PoliceComicSansMS,"F1 = Aide",0,0xf0f0c0);

	HgDeplacerObjet(ObjetTestPave1,100,100,600,AngleRotationObjetTest,AngleRotationObjetTest,AngleRotationObjetTest);
	HgDeplacerObjet(ObjetTestPave2,100,-100,600,AngleRotationObjetTest,0,AngleRotationObjetTest);
	HgDeplacerObjet(ObjetTestPave3,-100,-100,600,0,AngleRotationObjetTest,AngleRotationObjetTest);
	HgDeplacerObjet(ObjetTestSphere1,-100,100,600,0,0,0);
	AngleRotationObjetTest = AngleRotationObjetTest + 11930464;
	HgAfficherLR(&Camera1);

	FPS = HgObtenirFPS();
	HgConvertirWORDversASCII(FPS,&TamponFPS);
	TamponFPS[5]=0;			//ne garde que les bons chiffres
	HgAfficherTexte(600,10,PoliceComicSansMS,&TamponFPS,0,0xc0c0ff);
	HgAfficherTexte(670,10,PoliceComicSansMS,"FPS",0,0xc0c0ff);

	if (AideON == 1)
	{ HgAfficherImageSpec(192,144,0,0,0,0,ImageAide,0,0x50,0xc0c0ff);}

	ValeurXincremental++;
	HgAfficher();
	return;

	case WM_CLOSE:
		HgTerminerAffichage();
		StatutSession = 0;
		ExitProcess(0);
		return;

	 case WM_QUIT:
		HgTerminerAffichage();
		StatutSession = 0;
		ExitProcess(0);
	 	return;

	}
	DefWindowProc(hdlg,mssg,wParam,lParam);
	return;
}

Conclusion :


Si vous avez des questions, remarques, demandes... Je vous écoute.
Pour ceux qui se poserait la question, les instructions bizarres que j'utilise sont le jeu d'instructions 'SSE' (y a bon, mangez-en !).

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.