Raytracer en temps réel et en assembleur

Soyez le premier à donner votre avis sur cette source.

Vue 8 591 fois - Téléchargée 1 893 fois

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

Ajouter un commentaire Commentaires
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

Oulà, désolé pour le temps de réponse de 2 ans.

Concernant ton problème il est assez simple : tu doit mettre Visual C++ en mode "Compiler comme du code C".
Messages postés
573
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
20 avril 2021
2
visual c++ me dit,
demo.cpp(35) : error C2664: 'HgCreerAffichage' : impossible de convertir le paramètre 1 de 'void (__stdcall *)(HWND,UINT,WPARAM,LPARAM)' en 'DWORD'
Aucun contexte dans lequel cette conversion est possible
demo.cpp(67) : error C2373: 'Procedure3D' : redéfinition ; modificateurs de type différents
f:\assembleur\raytracer\demo.cpp(7) : voir la déclaration de 'Procedure3D'
demo.cpp(223) : error C2664: 'HgAfficherLR' : impossible de convertir le paramètre 1 de 'HgCamera *__w64 ' en 'DWORD *'
Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
demo.cpp(226) : error C3861: 'HgConvertirWORDversASCII' : identificateur introuvable
demo.cpp(228) : error C2664: 'HgAfficherTexte' : impossible de convertir le paramètre 4 de 'char (*__w64 )[10]' en 'char *'
Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
Messages postés
573
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
20 avril 2021
2
Salut,
Serait-il possible de rajouter les fichiers de compilation de visual c++ 2008 ?.
Ainsi que tous les fichiers nécessaires a la compilation ?
.dsp .dsw .sln ......bat
Merci
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

Concernant HgConvertir : désolé, je n'avait Uploadé que les fichiers qui s'occupait du RayTracing. Je viens de remplacer le .zip par la même démonstration, mais avec l'intégralité de la librairie.

Et je ne savais pas pour Virtual Alloc. Ce sera en effet plus simple d'avoir directement une adresse alignée, merci pour l'information.
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
26
Je ne trouve pas l'implémentation de HgConvertirWORDversASCII().

Tu peux supprimer tout un tas de calculs inutiles, VirtualAlloc retourne une adresse direct alignée sur 16.
Précalcule tout ton besoin mémoire et tun n'appelleras VirtualAlloc qu'1 seule fois, ensuite tu placeras tes adresses dans le bloc mémoire retourné.

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.