15.1.3 Les matrices de projection OpenGl en C

Le principe est exactement le même que dans les fichiers Matrice4.h et Matrice4.cpp, c'est juste que les fonctions push, pop, depile seront écrites en C.

Écrivons le fichier PMat4fGl3c.h.

On commence comme d'habitude avec les macros :

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

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ptmatrice4fc.h"

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif


#endif

Puis, la définition du type PMat4fGl3 :

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
#ifndef __PMAT4FGL3C_H__
#define __PMAT4FGL3C_H__

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ptmatrice4fc.h"

#ifdef __cplusplus
extern "C" {
#endif

struct PMat4fGl3cStrutc{
	PtMatrice4fc mat;
	struct PMat4fGl3cStrutc* savePrevMat;
};

typedef struct PMat4fGl3cStrutc PMat4fGl3;

#ifdef __cplusplus
}
#endif


#endif

Après, on ajoute les fonctions d'allocation et de dés-allocation :

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
#ifndef __PMAT4FGL3C_H__
#define __PMAT4FGL3C_H__

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ptmatrice4fc.h"

#ifdef __cplusplus
extern "C" {
#endif

struct PMat4fGl3cStrutc{
	PtMatrice4fc mat;
	struct PMat4fGl3cStrutc* savePrevMat;
};

typedef struct PMat4fGl3cStrutc PMat4fGl3;

PMat4fGl3 * createPMat4fGl3();
void freePMat4fGl3(PMat4fGl3* mat);

#ifdef __cplusplus
}
#endif


#endif

Ensuite on ajoute les fonction push, pop, depile :

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 __PMAT4FGL3C_H__
#define __PMAT4FGL3C_H__

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ptmatrice4fc.h"

#ifdef __cplusplus
extern "C" {
#endif

struct PMat4fGl3cStrutc{
	PtMatrice4fc mat;
	struct PMat4fGl3cStrutc* savePrevMat;
};

typedef struct PMat4fGl3cStrutc PMat4fGl3;

PMat4fGl3 * createPMat4fGl3();
void freePMat4fGl3(PMat4fGl3* mat);

void pushPMat4fGl3(PMat4fGl3* mat);
int popPMat4fGl3(PMat4fGl3* mat);
void depilerPMat4fGl3(PMat4fGl3* mat);

#ifdef __cplusplus
}
#endif


#endif

Notez que l'on ajoute un PMat4fGl3 à la fin de chaque fonction, pour qu'elle soit unique (car on fait du C).

Enfin, on ajoute les fonctions pour manipuler la matrice :

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
#ifndef __PMAT4FGL3C_H__
#define __PMAT4FGL3C_H__

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ptmatrice4fc.h"

#ifdef __cplusplus
extern "C" {
#endif

struct PMat4fGl3cStrutc{
	PtMatrice4fc mat;
	struct PMat4fGl3cStrutc* savePrevMat;
};

typedef struct PMat4fGl3cStrutc PMat4fGl3;

PMat4fGl3 * createPMat4fGl3();
void freePMat4fGl3(PMat4fGl3* mat);

void pushPMat4fGl3(PMat4fGl3* mat);
int popPMat4fGl3(PMat4fGl3* mat);
void depilerPMat4fGl3(PMat4fGl3* mat);

void loadIdentityPMat4fGl3(PMat4fGl3* mat);
void translatePMat4fGl3(PMat4fGl3* mat, float x, float y, float z);
void scalePMat4fGl3(PMat4fGl3* mat, float x, float y, float z);
void rotatePMat4fGl3Rad(PMat4fGl3* mat, float angleRad, float x, float y, float z);
void rotatePMat4fGl3Deg(PMat4fGl3* mat, float angleDeg, float x, float y, float z);
void perspectivePMat4fGl3Rad(PMat4fGl3* mat, float angleRad, float ratio, float near, float far);
void perspectivePMat4fGl3Deg(PMat4fGl3* mat, float angleDeg, float ratio, float near, float far);
void lookAtPMat4fGl3(PMat4fGl3* mat, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);

#ifdef __cplusplus
}
#endif


#endif

Voilà pour le fichier PMat4fGl3c.h.

Écrivons le fichier PMat4fGl3c.c.

L'include de base :

1
#include "PMat4fGl3c.h"

Les fonctions d'allocation et de dé-allocation :

1
2
3
4
5
6
7
8
9
10
11
PMat4fGl3 * createPMat4fGl3(){
	PMat4fGl3 * mat = malloc(sizeof(PMat4fGl3));
	mat->savePrevMat = NULL;
	return mat;
}

void freePMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return;
	depilerPMat4fGl3(mat);
	free(mat);
}

Les fonction push, pop, depile :

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
void pushPMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return;
	PMat4fGl3* sauvegarde = malloc(sizeof(PMat4fGl3));
	// Si l'allocation réussit
	if(sauvegarde != NULL){
		// Copie des valeurs dans la nouvelle case
		memcpy(sauvegarde->mat, mat->mat, sizeof(PtMatrice4fc));
		// On pointe sur la sauvegarde précédente
		sauvegarde->savePrevMat = mat->savePrevMat;
		// Redéfinition du sommet de la pile
		mat->savePrevMat = sauvegarde;
	}
}

int popPMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return 0;
	PMat4fGl3 *matriceTmp = mat->savePrevMat;
	// Si la pile existe toujours
	if(matriceTmp != 0){
		// Copie des valeurs depuis la sauvegarde
		memcpy(mat->mat, matriceTmp->mat, sizeof(PtMatrice4fc));
		// Redéfinition du sommet de la pile
		mat->savePrevMat = matriceTmp->savePrevMat;
		matriceTmp->savePrevMat = NULL;
		free(matriceTmp);
		return 1;
	}else return 0;
}

void depilerPMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return;
	while(popPMat4fGl3(mat) != 0);
}

Les fonctions pour manipuler la matrice :

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
void depilerPMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return;
	while(popPMat4fGl3(mat) != 0);
}

void loadIdentityPMat4fGl3(PMat4fGl3* mat){
	if(mat == NULL) return;
	loadIdentityPtMat4f(mat->mat);
}

void translatePMat4fGl3(PMat4fGl3* mat, float x, float y, float z){
	if(mat == NULL) return;
	translatedPtMat4f(mat->mat, x, y, z);
}

void scalePMat4fGl3(PMat4fGl3* mat, float x, float y, float z){
	if(mat == NULL) return;
	scalePtMat4f(mat->mat, x, y, z);
}

void rotatePMat4fGl3Rad(PMat4fGl3* mat, float angleRad, float x, float y, float z){
	if(mat == NULL) return;
	rotatePtMat4fRad(mat->mat, angleRad, x, y, z);
}

void rotatePMat4fGl3Deg(PMat4fGl3* mat, float angleDeg, float x, float y, float z){
	if(mat == NULL) return;
	rotatePtMat4fDeg(mat->mat, angleDeg, x, y, z);
}

void perspectivePMat4fGl3Rad(PMat4fGl3* mat, float angleRad, float ratio, float near, float far){
	if(mat == NULL) return;
	perspectivePtMat4fRad(mat->mat, angleRad, ratio, near, far);
}

void perspectivePMat4fGl3Deg(PMat4fGl3* mat, float angleDeg, float ratio, float near, float far){
	if(mat == NULL) return;
	perspectivePtMat4fDeg(mat->mat, angleDeg, ratio, near, far);
}

void lookAtPMat4fGl3(PMat4fGl3* mat, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ){
	if(mat == NULL) return;
	lookAtPtMat4f(mat->mat, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
}

Voici les fichiers que nous venons d'écrire :