Browse code

Add cpp-v2

Ingemar Ragnemalm authored on 21/02/2024 20:24:29 • Robert Cranston committed on 21/02/2024 20:24:29
Showing 22 changed files

1 1
deleted file mode 100755
2 2
Binary files a/common/._LittleOBJLoader.c and /dev/null differ
3 3
deleted file mode 100755
4 4
Binary files a/common/._LoadTGA.c and /dev/null differ
5 5
deleted file mode 100755
6 6
Binary files a/common/._VectorUtils3.c and /dev/null differ
7 7
deleted file mode 100755
8 8
Binary files a/common/._VectorUtils3.h and /dev/null differ
... ...
@@ -15,6 +15,8 @@
15 15
 // 200405: Added a few typecasts that were missing.
16 16
 // 210219: Shader errors are now visible on new VS19.
17 17
 // 210324: Compiling without fragment shader is now allowed
18
+// 220113: Removed the last remains of VS support. Use a system that
19
+// can handle printf! From now on, I will use CodeBlocks on Windows.
18 20
 
19 21
 //#define GL3_PROTOTYPES
20 22
 #ifdef WIN32
... ...
@@ -84,29 +86,24 @@ void printProgramInfoLog(GLuint obj, const char *vfn, const char *ffn,
84 86
 	GLint infologLength = 0;
85 87
 	GLint charsWritten  = 0;
86 88
 	char *infoLog;
87
-	char msg[2048] = "\n";
88 89
 
89 90
 	glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
90 91
 
91 92
 	if (infologLength > 2)
92 93
 	{
93 94
 		if (ffn == NULL)
94
-			sprintf(msg, "[From %s:]\n", vfn);
95
+			fprintf(stderr, "[From %s:]\n", vfn);
95 96
 		else
96 97
 		if (gfn == NULL)
97
-			sprintf(msg, "[From %s+%s:]\n", vfn, ffn);
98
+			fprintf(stderr, "[From %s+%s:]\n", vfn, ffn);
98 99
 		else
99 100
 		if (tcfn == NULL || tefn == NULL)
100
-			sprintf(msg, "[From %s+%s+%s:]\n", vfn, ffn, gfn);
101
+			fprintf(stderr, "[From %s+%s+%s:]\n", vfn, ffn, gfn);
101 102
 		else
102
-			sprintf(msg, "[From %s+%s+%s+%s+%s:]\n", vfn, ffn, gfn, tcfn, tefn);
103
-		if (strlen(msg) > 1)
104
-
105
-		fputs(msg, stderr);
103
+			fprintf(stderr, "[From %s+%s+%s+%s+%s:]\n", vfn, ffn, gfn, tcfn, tefn);
106 104
 		infoLog = (char *)malloc(infologLength);
107 105
 		glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
108
-		fputs(infoLog, stderr);
109
-		fputs("\n", stderr);
106
+		fprintf(stderr, "%s\n",infoLog);
110 107
 		free(infoLog);
111 108
 	}
112 109
 }
... ...
@@ -244,40 +241,6 @@ void printError(const char *functionName)
244 241
 }
245 242
 
246 243
 
247
-/*
248
-
249
-// Keymap mini manager
250
-// Important! Uses glutKeyboardFunc/glutKeyboardUpFunc so you can't use them
251
-// elsewhere or they will conflict.
252
-// (This functionality is built-in in MicroGlut, as "glutKeyIsDown" where this conflict should not exist.)
253
-
254
-char keymap[256];
255
-
256
-char keyIsDown(unsigned char c)
257
-{
258
-	return keymap[(unsigned int)c];
259
-}
260
-
261
-void keyUp(unsigned char key, int x, int y)
262
-{
263
-	keymap[(unsigned int)key] = 0;
264
-}
265
-
266
-void keyDown(unsigned char key, int x, int y)
267
-{
268
-	keymap[(unsigned int)key] = 1;
269
-}
270
-
271
-void initKeymapManager()
272
-{
273
-	int i;
274
-	for (i = 0; i < 256; i++) keymap[i] = 0;
275
-
276
-	glutKeyboardFunc(keyDown);
277
-	glutKeyboardUpFunc(keyUp);
278
-}
279
-*/
280
-
281 244
 // FBO
282 245
 
283 246
 //----------------------------------FBO functions-----------------------------------
284 247
deleted file mode 100755
... ...
@@ -1,1323 +0,0 @@
1
-// Little OBJ loader
2
-// Ingemar's little OBJ loader
3
-// Formerly named LoadOBJ or loadobj
4
-// by Ingemar Ragnemalm 2005, 2008, 2019, 2021
5
-
6
-// Original version 2005 was extremely simple and intended for use with old OpenGL immediate mode.
7
-// Additions and reorganization by Mikael Kalms 2008
8
-// 120913: Revised LoadModelPlus/DrawModel by Jens.
9
-// Partially corrected formatting. (It is a mess!)
10
-// 130227: Error reporting in DrawModel
11
-// 130422: Added ScaleModel
12
-// 150909: Frees up temporary "Mesh" memory i LoadModel. Thanks to Simon Keisala for finding this!
13
-// Added DisposeModel. Limited the number of error printouts, thanks to Rasmus Hytter for this suggestion!
14
-// 160302: Uses fopen_s on Windows, as suggested by Jesper Post. Should reduce warnings a bit.
15
-// 160510: Uses calloc instead of malloc (for safety) in many places where it could possibly cause problems.
16
-// 170406: Added "const" to string arguments to make C++ happier.
17
-// 190416: free mesh->coordStarts properly.
18
-// 191110: Finally! Multi-part OBJ files work! Renamed LoadModelPlus to LoadModel.
19
-// and added LoadModelSet! The old LoadModel was removed. Converted to use vec2/vec3
20
-// instead of arrays of float. It is now dependent on VectorUtils3. If you want to
21
-// make it independent of VectorUtils3, only a few structs and functions have to be replaced.
22
-// MTL support working! Parser totally rewritten. Officially renamed to Ingemars Little OBJ Loader,
23
-// LOL for short! And boy did I find a nice acronym!
24
-// 210125: Corrected types in LoadDataToModel. Corrected material disposal in the still badly tested DisposeModel.
25
-// 210218: Allows TAB between parts of string.
26
-// 210304: Corrected bad allocation size on row 538, found by Jens Lindgren, who also found glDeleteVertexArrays in DisposeModel.
27
-// 210422: Change by Felicia Castenbrandt, around row 415, copy path or source. This change is likely to be needed in some other places.
28
-// 210502: Dispose the material name list, omission found by Jens Lindgren.
29
-
30
-// Usage:
31
-// Load simple models with LoadModel. Multi-part models are loaded with LoadModelSet.
32
-// DrawModel will draw the model, or, for a multi-part model, one part.
33
-// If you need to modify a model on the CPU, you can do that and re-upload
34
-// with LoadDataToModel.
35
-// There is no longer any call that only loads the data, but you can
36
-// make your own by taking out the GPU upload from LoadModel.
37
-
38
-// This is free software. I appreciate credits in derivate products or
39
-// if it is used in public products.
40
-
41
-#include "LittleOBJLoader.h"
42
-#include <stdio.h>
43
-#include <stdlib.h>
44
-#include <string.h>
45
-#include <math.h>
46
-#include "VectorUtils3.h"
47
-
48
-#if defined(_WIN32)
49
-	#define sscanf sscanf_s
50
-#endif
51
-
52
-
53
-static char atLineEnd = 0;
54
-static char atFileEnd = 0;
55
-
56
-static char ParseString(char *line, int *pos, char *s)
57
-{
58
-	int i = 0;
59
-	char c;
60
-	c = line[(*pos)++];
61
-	while (c == 32 || c == 9) // Important change 210218
62
-		c = line[(*pos)++]; // Skip leading spaces
63
-	while (c != 0 && c != 32 && c != 9  && c != EOF && c != '/' && i < 254)
64
-	{
65
-		s[i++] = c;
66
-		c = line[(*pos)++];
67
-	}
68
-	atLineEnd = (c == 0);
69
-	s[i] = 0;
70
-	
71
-	return c;
72
-}
73
-
74
-static float ParseFloat(char *line, int *pos)
75
-{
76
-	float floatValue = 0.0;
77
-	char s[255];
78
-	ParseString(line, pos, s);
79
-	sscanf(s, "%f", &floatValue);
80
-	if (isnan(floatValue) || isinf(floatValue))
81
-		floatValue = 0.0;
82
-	return floatValue;
83
-}
84
-
85
-static int ParseInt(char *line, int *pos, char *endc)
86
-{
87
-	int intValue = 0;
88
-	char s[255];
89
-	char c = ParseString(line, pos, s);
90
-	if (endc != NULL) *endc = c;
91
-	if (strlen(s) == 0)
92
-		intValue = -1; // Nothing found!
93
-	else
94
-		sscanf(s, "%d", &intValue);
95
-	return intValue;
96
-}
97
-
98
-static vec3 ParseVec3(char *line, int *pos)
99
-{
100
-	vec3 v;
101
-	v.x = ParseFloat(line, pos);
102
-	v.y = ParseFloat(line, pos);
103
-	v.z = ParseFloat(line, pos);
104
-	return v;
105
-}
106
-
107
-void ParseLine(FILE *fp, char *line)
108
-{
109
-	int i, j;
110
-	char c = '_';
111
-	for (i = 0, j= 0; i < 2048; i++)
112
-	{
113
-		c = getc(fp);
114
-		if (c != 10 && c != 13)
115
-			line[j++] = c;
116
-		if (c == EOF || ((c == 10 || c == 13) && j > 0))
117
-		{
118
-			if (c == EOF)
119
-				atFileEnd = 1;
120
-			line[j] = 0;
121
-			return;
122
-		}
123
-	}
124
-	line[j] = 0;
125
-	return;
126
-}
127
-
128
-
129
-// Dispose the strings in the materials list
130
-static void DisposeMtlList(Mtl **materials)
131
-{
132
-	if (materials != NULL)
133
-	for (int i = 0; materials[i] != NULL; i++)
134
-		free(materials[i]);
135
-	free(materials);
136
-}
137
-
138
-static Mtl **ParseMTL(char *filename)
139
-{
140
-	Mtl *m;
141
-	char s[255];
142
-	char line[2048];
143
-	int pos;
144
-	Mtl **materials = NULL;
145
-	FILE *fp;
146
-
147
-	// It seems Windows/VS doesn't like fopen any more, but fopen_s is not on the others.
148
-	#if defined(_WIN32)
149
-	fopen_s(&fp, filename, "r");
150
-	#else
151
-	fp = fopen(filename, "rb"); // rw works everywhere except Windows?
152
-	#endif
153
-	if (fp == NULL)
154
-		return NULL;
155
-	atLineEnd = 0;
156
-	atFileEnd = 0;
157
-	int matcount = 0;
158
-
159
-	while (!atFileEnd)
160
-	{
161
-		ParseLine(fp, line);
162
-		pos = 0;
163
-		ParseString(line, &pos, s);
164
-		if (strcmp(s, "newmtl") == 0)
165
-			matcount++;
166
-	}
167
-	rewind(fp);
168
-
169
-	materials = (Mtl **)calloc(sizeof(MtlPtr)*(matcount+1), 1);
170
-
171
-	matcount = 0;
172
-	atLineEnd = 0;
173
-	atFileEnd = 0;
174
-	
175
-	while (!atFileEnd)
176
-	{
177
-		ParseLine(fp, line);
178
-		pos = 0;
179
-		ParseString(line, &pos, s);
180
-
181
-		// NEW MATERIAL!
182
-		if (strcmp(s, "newmtl") == 0)
183
-		{
184
-			matcount++;
185
-			materials[matcount-1] = (Mtl *)calloc(sizeof(Mtl),1);
186
-			m = materials[matcount-1];
187
-			materials[matcount] = NULL;
188
-			
189
-			ParseString(line, &pos, m->newmtl);
190
-		}
191
-
192
-		if (m != NULL)
193
-		{
194
-			if (strcmp(s, "Ka") == 0)
195
-				m->Ka = ParseVec3(line, &pos);
196
-			if (strcmp(s, "Kd") == 0)
197
-				m->Kd = ParseVec3(line, &pos);
198
-			if (strcmp(s, "Ks") == 0)
199
-				m->Ks = ParseVec3(line, &pos);
200
-			if (strcmp(s, "Ke") == 0)
201
-				m->Ke = ParseVec3(line, &pos);
202
-			if (strcmp(s, "Tr") == 0)
203
-			{
204
-				m->Tr = ParseFloat(line, &pos);
205
-				m->d = 1 - m->Tr;
206
-			}
207
-			if (strcmp(s, "d") == 0)
208
-			{
209
-				m->d = ParseFloat(line, &pos);
210
-				m->Tr = 1 - m->d;
211
-			}
212
-
213
-			if (strcmp(s, "illum") == 0)
214
-				m->illum = ParseInt(line, &pos, NULL);
215
-
216
-			if (strcmp(s, "map_Ka") == 0)
217
-				ParseString(line, &pos, m->map_Ka);
218
-			if (strcmp(s, "map_Kd") == 0)
219
-				ParseString(line, &pos, m->map_Kd);
220
-			if (strcmp(s, "map_Ks") == 0)
221
-				ParseString(line, &pos, m->map_Ks);
222
-			if (strcmp(s, "map_Ke") == 0)
223
-				ParseString(line, &pos, m->map_Ke);
224
-			if (strcmp(s, "map_d") == 0)
225
-				ParseString(line, &pos, m->map_d);
226
-			if (strcmp(s, "map_bump") == 0)
227
-				ParseString(line, &pos, m->map_bump);
228
-			if (strcmp(s, "bump") == 0)
229
-				ParseString(line, &pos, m->map_bump);
230
-		}
231
-	}
232
-	fclose(fp);
233
-
234
-	return materials;
235
-}
236
-
237
-typedef struct Mesh
238
-{
239
-	vec3	*vertices;
240
-	int		vertexCount;
241
-	vec3	*vertexNormals;
242
-	int		normalsCount;
243
-	vec2	*textureCoords;
244
-	int		texCount;
245
-	
246
-	int		*coordIndex;
247
-	int		*normalsIndex;
248
-	int		*textureIndex;
249
-	int		coordCount; // Number of indices in each index struct
250
-	
251
-	// Borders between groups
252
-	int		*coordStarts;
253
-	int		groupCount;
254
-	
255
-	char	*materialName;
256
-} Mesh, *MeshPtr;
257
-
258
-// Globals set by LoadObj
259
-static int vertCount, texCount, normalsCount, coordCount;
260
-static int zeroFix;
261
-static char hasPositionIndices;
262
-static char hasNormalIndices;
263
-static char hasTexCoordIndices;
264
-
265
-// List of materials
266
-Mtl **gMaterials;
267
-char **gMtlNameList;
268
-char *gMtlLibName = NULL;
269
-
270
-static char ParseOBJ(const char *filename, MeshPtr theMesh)
271
-{
272
-	int lastCoordCount = -1;
273
-	FILE *fp;
274
-	
275
-	// It seems Windows/VS doesn't like fopen any more, but fopen_s is not on the others.
276
-	#if defined(_WIN32)
277
-	fopen_s(&fp, filename, "r");
278
-	#else
279
-	fp = fopen(filename, "rb"); // rw works everywhere except Windows?
280
-	#endif
281
-	if (fp == NULL)
282
-		return -1;
283
-
284
-// These must be taken care of by the caller!
285
-	vertCount=0;
286
-	texCount=0;
287
-	normalsCount=0;
288
-	coordCount=0;
289
-
290
-	atLineEnd = 0;
291
-	atFileEnd = 0;
292
-		
293
-	while (!atFileEnd)
294
-	{
295
-		char line[2048];
296
-		ParseLine(fp, line);
297
-		int pos = 0;
298
-		
299
-		char s[256];
300
-		ParseString(line, &pos, s);
301
-		
302
-		if (strcmp(s, "v") == 0)
303
-		{
304
-			vec3 v = ParseVec3(line, &pos);
305
-			if (theMesh->vertices != NULL)
306
-				theMesh->vertices[vertCount++] = v;
307
-			else
308
-				vertCount += 1;
309
-		}
310
-		if (strcmp(s, "vn") == 0)
311
-		{
312
-			vec3 v = ParseVec3(line, &pos);			
313
-			if (theMesh->vertexNormals != NULL)
314
-				theMesh->vertexNormals[normalsCount++] = v;
315
-			else
316
-				normalsCount += 1;
317
-		}
318
-		if (strcmp(s, "vt") == 0)
319
-		{
320
-			vec3 v = ParseVec3(line, &pos);
321
-			if (theMesh->textureCoords != NULL)
322
-			{
323
-				theMesh->textureCoords[texCount].x = v.x;
324
-				theMesh->textureCoords[texCount++].y = v.y;
325
-			}
326
-			else
327
-				texCount += 1;
328
-		}
329
-		if (strcmp(s, "f") == 0)
330
-		{
331
-		// Unknown number of singeltons or triplets!
332
-			
333
-			int p = -1;
334
-			int i = -1;
335
-			int p1;
336
-			char *ns;
337
-			char done = 0;
338
-			for (i = pos ; !done; pos++)
339
-			{
340
-				if (line[pos] == 0)
341
-					done = 1;
342
-				if (p >= 0) // in triplet)
343
-				{
344
-					char c = line[pos];
345
-					if (c == '/' || c == ' ' || c == 0)
346
-					{
347
-						ns = &line[p1]; // Start of substring
348
-						line[pos] = 0; // End of substring
349
-						if (p1 != pos)
350
-						{
351
-							i = atoi(ns);
352
-							if (i == 0)
353
-								zeroFix = 1;
354
-							if (i < 0)
355
-							{
356
-								switch (p)
357
-								{
358
-									case 0: i = vertCount + i + 1; break;
359
-									case 1: i = texCount + i + 1; break;
360
-									case 2: i = normalsCount + i + 1; break;
361
-								}
362
-							}
363
-							i = i + zeroFix;
364
-						}
365
-						else
366
-							i = 0; // -1
367
-						
368
-						if (i > 0)
369
-						switch (p)
370
-						{
371
-							case 0:
372
-								if (theMesh->coordIndex != NULL)
373
-									theMesh->coordIndex[coordCount-1] = i-1;
374
-								break;
375
-							case 1:
376
-								if (theMesh->textureIndex != NULL)
377
-									if (i >= 0)
378
-										theMesh->textureIndex[coordCount-1] = i-1;
379
-								hasTexCoordIndices = 1;
380
-								break;
381
-							case 2:
382
-								if (theMesh->normalsIndex != NULL)
383
-									if (i >= 0)
384
-										theMesh->normalsIndex[coordCount-1] = i-1;
385
-								hasNormalIndices = 1;
386
-								break;
387
-						}
388
-						p1 = pos + 1;
389
-						p++;
390
-					}
391
-					if (c == ' ')
392
-					{
393
-						p = -1; // Next triplet
394
-					}
395
-				}
396
-				else // Wait for non-space
397
-				if (line[pos] != ' ')
398
-				{
399
-					if (!done)
400
-						coordCount++;
401
-					p = 0; // Triplet starts!
402
-					p1 = pos;
403
-				}
404
-			}
405
-			
406
-			if (theMesh->coordIndex != NULL)
407
-				theMesh->coordIndex[coordCount] = -1;
408
-			if (theMesh->textureIndex != NULL)
409
-				theMesh->textureIndex[coordCount] = -1;
410
-			if (theMesh->normalsIndex != NULL)
411
-				theMesh->normalsIndex[coordCount] = -1;
412
-			coordCount++;
413
-		}
414
-		if (strcmp(s, "mtllib") == 0)
415
-		{
416
-			// Save file name for later
417
-			char libname[256];
418
-			
419
-			// Added by Felicia Castenbrandt: Get path of main file, if any
420
-        	char temp[255];
421
-			int index = 0;
422
-
423
-			//find index of last /
424
-			for(int i = 0; i < strlen(filename); i++)
425
-				if(filename[i] == '/')
426
-					index = i;
427
-
428
-			//copy everything before the last / to temp
429
-			if (index != 0)
430
-			{
431
-				for(int i = 0; i < index+1; i++)
432
-				{
433
-					char ch = filename[i];
434
-					strncat(temp, &ch, 1);
435
-				}
436
-			}
437
-			// End of addition
438
-			
439
-			
440
-			/*char c =*/ ParseString(line, &pos, libname);
441
-			gMtlLibName = (char *)malloc(strlen(libname)+1);
442
-#if defined(_WIN32)
443
-			strcpy_s(gMtlLibName, strlen(libname) + 1, libname);
444
-#else
445
-			strcpy(gMtlLibName, libname);
446
-#endif
447
-
448
-		}
449
-		if (strcmp(s, "usemtl") == 0)
450
-		{
451
-			// Groups are only identified by usemtl!
452
-			
453
-			if (coordCount > 0) // If no data has been seen, this must be the first group!
454
-			{
455
-				if (lastCoordCount != coordCount) // must not be the same; empty group (happens if a model has both "g" and "o")
456
-				{
457
-					theMesh->groupCount += 1;
458
-					if (theMesh->coordStarts != NULL) // NULL if we are just counting
459
-						theMesh->coordStarts[theMesh->groupCount] = coordCount;
460
-
461
-					lastCoordCount = coordCount;
462
-				}
463
-				else
464
-					printf("Ignored part!\n");
465
-			}
466
-			
467
-			if (gMtlNameList != NULL)
468
-			{
469
-				// Save matname for later
470
-				char matname[255];
471
-				ParseString(line, &pos, matname);
472
-				gMtlNameList[theMesh->groupCount] = (char *)malloc(strlen(matname)+1);
473
-#if defined(_WIN32)
474
-				strcpy_s(gMtlNameList[theMesh->groupCount], strlen(matname) + 1, matname);
475
-#else
476
-				strcpy(gMtlNameList[theMesh->groupCount], matname);
477
-#endif
478
-
479
-
480
-			}
481
-		}
482
-	} // While
483
-	
484
-	// Add last groups *if* there was more data since last time!
485
-	if (coordCount > lastCoordCount)
486
-	{
487
-		theMesh->groupCount += 1; // End of last group
488
-		if (theMesh->coordStarts != NULL)
489
-			theMesh->coordStarts[theMesh->groupCount] = coordCount;
490
-	}
491
-		
492
-	fclose(fp);
493
-	
494
-	if (gMtlLibName != NULL)
495
-		gMaterials = ParseMTL(gMtlLibName);
496
-	// else try based on filename: filename.obj -> filename.mtl or filename_obj.mtl
497
-	if (gMaterials == NULL)
498
-	if (strlen(filename) > 4)
499
-	{
500
-		char tryname[255];
501
-		strcpy(tryname, filename);
502
-		tryname[strlen(tryname) - 4] = '_';
503
-		strcat(tryname, ".mtl");
504
-		gMaterials = ParseMTL(tryname);
505
-	}
506
-	if (gMaterials == NULL)
507
-	if (strlen(filename) > 4)
508
-	{
509
-		char tmpname[255];
510
-		strcpy(tmpname, filename);
511
-		tmpname[strlen(tmpname) - 4] = 0;
512
-		strcat(tmpname, ".mtl");
513
-		gMaterials = ParseMTL(tmpname);
514
-	}
515
-	return 0;
516
-}
517
-
518
-// Load raw, unprocessed OBJ data!
519
-static struct Mesh * LoadOBJ(const char *filename)
520
-{
521
-	// Reads once to find sizes, again to fill buffers
522
-	Mesh *theMesh;
523
-	
524
-	// Allocate Mesh but not the buffers
525
-	theMesh = (Mesh *)calloc(sizeof(Mesh), 1);
526
-
527
-	hasPositionIndices = 1;
528
-	hasTexCoordIndices = 0;
529
-	hasNormalIndices = 0;
530
-
531
-	theMesh->coordStarts = NULL;
532
-	theMesh->groupCount = 0;
533
-	gMtlNameList = NULL;
534
-
535
-// Dispose if they exist!
536
-	gMtlLibName = NULL;
537
-	gMaterials = NULL;
538
-
539
-	vertCount=0;
540
-	texCount=0;
541
-	normalsCount=0;
542
-	coordCount=0;
543
-	zeroFix = 0;
544
-		
545
-	// Parse for size
546
-	ParseOBJ(filename, theMesh);
547
-
548
-	// Allocate arrays!
549
-	if (vertCount > 0)
550
-		theMesh->vertices = (vec3 *)malloc(sizeof(vec3) * vertCount);
551
-	if (texCount > 0)
552
-		theMesh->textureCoords = (vec2 *)malloc(sizeof(vec2) * texCount);
553
-	if (normalsCount > 0)
554
-		theMesh->vertexNormals = (vec3 *)malloc(sizeof(vec3) * normalsCount);
555
-	if (hasPositionIndices)
556
-		theMesh->coordIndex = (int *)calloc(coordCount, sizeof(int));
557
-	if (hasNormalIndices)
558
-		theMesh->normalsIndex = (int *)calloc(coordCount, sizeof(int));
559
-	if (hasTexCoordIndices)
560
-		theMesh->textureIndex = (int *)calloc(coordCount, sizeof(int));
561
-
562
-	gMtlNameList = (char **)calloc(sizeof(char *) * (theMesh->groupCount+1), 1);
563
-	theMesh->coordStarts = (int *)calloc(sizeof(int) * (theMesh->groupCount+2), 1); // Length found on last pass
564
-	theMesh->groupCount = 0;
565
-
566
-	// Zero again
567
-	vertCount=0;
568
-	texCount=0;
569
-	normalsCount=0;
570
-	coordCount=0;
571
-
572
-	// Parse again for filling buffers
573
-	ParseOBJ(filename, theMesh);
574
-	
575
-	theMesh->vertexCount = vertCount;
576
-	theMesh->coordCount = coordCount;
577
-	theMesh->texCount = texCount;
578
-	theMesh->normalsCount = normalsCount;
579
-
580
-	return theMesh;
581
-}
582
-
583
-void DecomposeToTriangles(struct Mesh *theMesh)
584
-{
585
-	int i, vertexCount, triangleCount;
586
-	int *newCoords, *newNormalsIndex, *newTextureIndex;
587
-	int newIndex = 0; // Index in newCoords
588
-	int first = 0;
589
-
590
-	// 1.1 Calculate how big the list will become
591
-	
592
-	vertexCount = 0; // Number of vertices in current polygon
593
-	triangleCount = 0; // Resulting number of triangles
594
-	for (i = 0; i < theMesh->coordCount; i++)
595
-	{
596
-		if (theMesh->coordIndex[i] == -1)
597
-		{
598
-		if (vertexCount > 2) triangleCount += vertexCount - 2;
599
-			vertexCount = 0;
600
-		}
601
-		else
602
-		{
603
-			vertexCount = vertexCount + 1;
604
-		}
605
-	}
606
-		
607
-	newCoords = (int *)calloc(triangleCount * 3, sizeof(int));
608
-	if (theMesh->normalsIndex != NULL)
609
-		newNormalsIndex = (int *)calloc(triangleCount * 3, sizeof(int));
610
-	if (theMesh->textureIndex != NULL)
611
-		newTextureIndex = (int *)calloc(triangleCount * 3, sizeof(int));
612
-	
613
-	// 1.2 Loop through old list and write the new one
614
-	// Almost same loop but now it has space to write the result
615
-	vertexCount = 0;
616
-	for (i = 0; i < theMesh->coordCount; i++)
617
-	{
618
-		if (theMesh->coordIndex[i] == -1)
619
-		{
620
-			first = i + 1;
621
-			vertexCount = 0;
622
-		}
623
-		else
624
-		{
625
-			vertexCount = vertexCount + 1;
626
-			if (vertexCount > 2)
627
-			{
628
-				newCoords[newIndex++] = theMesh->coordIndex[first];
629
-				newCoords[newIndex++] = theMesh->coordIndex[i-1];
630
-				newCoords[newIndex++] = theMesh->coordIndex[i];
631
-				if (theMesh->normalsIndex != NULL)
632
-				{
633
-					newNormalsIndex[newIndex-3] = theMesh->normalsIndex[first];
634
-					newNormalsIndex[newIndex-2] = theMesh->normalsIndex[i-1];
635
-					newNormalsIndex[newIndex-1] = theMesh->normalsIndex[i];
636
-				}
637
-				if (theMesh->textureIndex != NULL)
638
-				{
639
-					newTextureIndex[newIndex-3] = theMesh->textureIndex[first];
640
-					newTextureIndex[newIndex-2] = theMesh->textureIndex[i-1];
641
-					newTextureIndex[newIndex-1] = theMesh->textureIndex[i];
642
-				}
643
-			}
644
-		}
645
-	}
646
-	
647
-	free(theMesh->coordIndex);
648
-	theMesh->coordIndex = newCoords;
649
-	theMesh->coordCount = triangleCount * 3;
650
-	if (theMesh->normalsIndex != NULL)
651
-	{
652
-		free(theMesh->normalsIndex);
653
-		theMesh->normalsIndex = newNormalsIndex;
654
-	}
655
-	if (theMesh->textureIndex != NULL)
656
-	{
657
-		free(theMesh->textureIndex);
658
-		theMesh->textureIndex = newTextureIndex;
659
-	}
660
-} // DecomposeToTriangles
661
-
662
-static void GenerateNormals(Mesh* mesh)
663
-{
664
-	// If model has vertices but no vertexnormals, generate normals
665
-	if (mesh->vertices && !mesh->vertexNormals)
666
-	{
667
-		int face;
668
-		int normalIndex;
669
-
670
-		mesh->vertexNormals = (vec3 *)calloc(sizeof(vec3) * mesh->vertexCount, 1);
671
-		mesh->normalsCount = mesh->vertexCount;
672
-
673
-		mesh->normalsIndex = (int *)calloc(mesh->coordCount, sizeof(GLuint));
674
-		memcpy(mesh->normalsIndex, mesh->coordIndex, sizeof(GLuint) * mesh->coordCount);
675
-
676
-		for (face = 0; face * 3 < mesh->coordCount; face++)
677
-		{
678
-			int i0 = mesh->coordIndex[face * 3 + 0];
679
-			int i1 = mesh->coordIndex[face * 3 + 1];
680
-			int i2 = mesh->coordIndex[face * 3 + 2];
681
-			
682
-			vec3 v0 = VectorSub(mesh->vertices[i1], mesh->vertices[i0]);
683
-			vec3 v1 = VectorSub(mesh->vertices[i2], mesh->vertices[i0]);
684
-			vec3 v2 = VectorSub(mesh->vertices[i2], mesh->vertices[i1]);
685
-
686
-			float sqrLen0 = dot(v0, v0);
687
-			float sqrLen1 = dot(v1, v1);
688
-			float sqrLen2 = dot(v2, v2);
689
-
690
-			float len0 = (sqrLen0 >= 1e-6f) ? sqrt(sqrLen0) : 1e-3f;
691
-			float len1 = (sqrLen1 >= 1e-6f) ? sqrt(sqrLen1) : 1e-3f;
692
-			float len2 = (sqrLen2 >= 1e-6f) ? sqrt(sqrLen2) : 1e-3f;
693
-
694
-			float influence0 = dot(v0, v1) / (len0 * len1);
695
-			float influence1 = -dot(v0, v2) / (len0 * len2);
696
-			float influence2 = dot(v1, v2) / (len1 * len2);
697
-
698
-			float angle0 = (influence0 >= 1.f) ? 0 : 
699
-				(influence0 <= -1.f) ? M_PI : acos(influence0);
700
-			float angle1 = (influence1 >= 1.f) ? 0 : 
701
-				(influence1 <= -1.f) ? M_PI : acos(influence1);
702
-			float angle2 = (influence2 >= 1.f) ? 0 : 
703
-				(influence2 <= -1.f) ? M_PI : acos(influence2);
704
-
705
-			vec3 normal = cross(v0, v1);
706
-			mesh->vertexNormals[i0] = VectorAdd(ScalarMult(normal, angle0), mesh->vertexNormals[i0]);
707
-			mesh->vertexNormals[i1] = VectorAdd(ScalarMult(normal, angle1), mesh->vertexNormals[i1]);
708
-			mesh->vertexNormals[i2] = VectorAdd(ScalarMult(normal, angle2), mesh->vertexNormals[i2]);
709
-		}
710
-
711
-		for (normalIndex = 0; normalIndex < mesh->normalsCount; normalIndex++)
712
-		{
713
-			float length = Norm(mesh->vertexNormals[normalIndex]);
714
-			if (length > 0.01f)
715
-				mesh->vertexNormals[normalIndex] = ScalarMult(mesh->vertexNormals[normalIndex], 1/length);
716
-		}
717
-	}
718
-}
719
-
720
-static Model* GenerateModel(Mesh* mesh)
721
-{
722
-	// Convert from Mesh format (multiple index lists) to Model format
723
-	// (one index list) by generating a new set of vertices/indices
724
-	// and where new vertices have been created whenever necessary
725
-
726
-	typedef struct
727
-	{
728
-		int positionIndex;
729
-		int normalIndex;
730
-		int texCoordIndex;
731
-		int newIndex;
732
-	} IndexTriplet;
733
-
734
-	int hashGap = 6;
735
-
736
-	int indexHashMapSize = (mesh->vertexCount * hashGap + mesh->coordCount);
737
-
738
-	IndexTriplet* indexHashMap = (IndexTriplet *)malloc(sizeof(IndexTriplet)
739
-							* indexHashMapSize);
740
-
741
-	int numNewVertices = 0;
742
-	int index;
743
-
744
-	int maxValue = 0;
745
-		
746
-	Model* model = (Model *)malloc(sizeof(Model));
747
-	memset(model, 0, sizeof(Model));
748
-
749
-	model->indexArray = (GLuint *)malloc(sizeof(GLuint) * mesh->coordCount);
750
-	model->numIndices = mesh->coordCount;
751
-
752
-	memset(indexHashMap, 0xff, sizeof(IndexTriplet) * indexHashMapSize);
753
-
754
-	for (index = 0; index < mesh->coordCount; index++)
755
-	{
756
-		IndexTriplet currentVertex = { -1, -1, -1, -1 };
757
-		int insertPos = 0;
758
-		if (mesh->coordIndex)
759
-			currentVertex.positionIndex = mesh->coordIndex[index];
760
-		if (mesh->normalsIndex)
761
-			currentVertex.normalIndex = mesh->normalsIndex[index];
762
-		if (mesh->textureIndex)
763
-			currentVertex.texCoordIndex = mesh->textureIndex[index];
764
-
765
-		if (maxValue < currentVertex.texCoordIndex)
766
-			maxValue = currentVertex.texCoordIndex;
767
- 
768
-		if (currentVertex.positionIndex >= 0)
769
-			insertPos = currentVertex.positionIndex * hashGap;
770
-
771
-		while (1)
772
-		{
773
-			if (indexHashMap[insertPos].newIndex == -1)
774
-				{
775
-					currentVertex.newIndex = numNewVertices++;
776
-					indexHashMap[insertPos] = currentVertex;
777
-					break;
778
-				}
779
-			else if (indexHashMap[insertPos].positionIndex
780
-				 == currentVertex.positionIndex
781
-				 && indexHashMap[insertPos].normalIndex
782
-				 == currentVertex.normalIndex
783
-				 && indexHashMap[insertPos].texCoordIndex
784
-				 == currentVertex.texCoordIndex)
785
-				{
786
-					currentVertex.newIndex = indexHashMap[insertPos].newIndex;
787
-					break;
788
-				}
789
-			else
790
-				insertPos++;
791
-		} 
792
-
793
-		model->indexArray[index] = currentVertex.newIndex;
794
-	}
795
-
796
-	if (mesh->vertices)
797
-		model->vertexArray = (vec3 *)malloc(sizeof(vec3) * numNewVertices);
798
-	if (mesh->vertexNormals)
799
-		model->normalArray = (vec3 *)malloc(sizeof(vec3) * numNewVertices);
800
-	if (mesh->textureCoords)
801
-		model->texCoordArray = (vec2 *)malloc(sizeof(vec2) * numNewVertices);
802
-	
803
-	model->numVertices = numNewVertices;
804
-
805
-	for (index = 0; index < indexHashMapSize; index++)
806
-	{
807
-		if (indexHashMap[index].newIndex != -1)
808
-		{
809
-			if (mesh->vertices)
810
-				model->vertexArray[indexHashMap[index].newIndex] = mesh->vertices[indexHashMap[index].positionIndex];
811
-			if (mesh->vertexNormals)
812
-			{
813
-				model->normalArray[indexHashMap[index].newIndex] = mesh->vertexNormals[indexHashMap[index].normalIndex];
814
-			}
815
-			if (mesh->textureCoords)
816
-				model->texCoordArray[indexHashMap[index].newIndex] = mesh->textureCoords[indexHashMap[index].texCoordIndex];
817
-		}
818
-	}
819
-
820
-	free(indexHashMap);
821
-
822
-	// If there is a material set, match materials to parts
823
-	if (gMaterials != NULL)
824
-	if (mesh->materialName != NULL)
825
-		for (int ii = 0; gMaterials[ii] != NULL; ii++)
826
-		{
827
-			Mtl *mtl = gMaterials[ii];
828
-			if (strcmp(mesh->materialName, mtl->newmtl) == 0)
829
-			{
830
-				// Copy mtl to model!
831
-				model->material = (Mtl *)malloc(sizeof(Mtl));
832
-				memcpy(model->material, mtl, sizeof(Mtl));
833
-
834
-				strcpy(model->material->map_Ka, mtl->map_Ka);
835
-				strcpy(model->material->map_Kd, mtl->map_Kd);
836
-				strcpy(model->material->map_Ks, mtl->map_Ks);
837
-				strcpy(model->material->map_Ke, mtl->map_Ke);
838
-				strcpy(model->material->map_Ns, mtl->map_Ns);
839
-				strcpy(model->material->map_d, mtl->map_d);
840
-				strcpy(model->material->map_bump, mtl->map_bump);
841
-			}
842
-		}
843
-
844
-	return model;
845
-}
846
-
847
-Mesh **SplitToMeshes(Mesh *m)
848
-{
849
-	int * mapc = (int *)malloc(m->vertexCount * sizeof(int));
850
-	int * mapt = (int *)malloc(m->texCount * sizeof(int));
851
-	int * mapn = (int *)malloc(m->normalsCount * sizeof(int));
852
-	
853
-	if (m == NULL || m ->vertices == NULL || m->vertexCount == 0)
854
-	{
855
-		printf("Illegal mesh!\n");
856
-		return NULL;
857
-	}
858
-	
859
-	Mesh **mm = (Mesh **)calloc(sizeof(Mesh *), m->groupCount+2);
860
-
861
-	for (int mi = 0; mi < m->groupCount; mi++) // For all sections
862
-	{
863
-		int from = m->coordStarts[mi];
864
-		int to = m->coordStarts[mi+1];
865
-		
866
-		mm[mi] = (Mesh *)calloc(sizeof(Mesh), 1); // allocate struct
867
-		
868
-		// Fill mapc, mapt, mapn with -1 (illegal index)
869
-		for (int ii = 0; ii < m->vertexCount; ii++)
870
-			mapc[ii] = -1;
871
-		for (int ii = 0; ii < m->texCount; ii++)
872
-			mapt[ii] = -1;
873
-		for (int ii = 0; ii < m->normalsCount; ii++)
874
-			mapn[ii] = -1;
875
-		
876
-		// Count number of entries needed
877
-		int intVertexCount = 0;
878
-		int intTexCount = 0;
879
-		int intNormalsCount = 0;
880
-		
881
-		for (int j = from; j < to; j++) // For all index triplets
882
-		{
883
-			int ix = m->coordIndex[j];
884
-			if (ix > -1)
885
-				if (mapc[ix] == -1)
886
-				{
887
-					mapc[ix] = ix;
888
-					intVertexCount++;
889
-				}
890
-			if (m->textureIndex != NULL)
891
-			{
892
-				ix = m->textureIndex[j];
893
-				if (ix > -1)
894
-					if (mapt[ix] == -1)
895
-					{
896
-						mapt[ix] = ix;
897
-						intTexCount++;
898
-					}
899
-			}
900
-			if (m->normalsIndex != NULL)
901
-			{
902
-				ix = m->normalsIndex[j];
903
-				if (ix > -1)
904
-					if (mapn[ix] == -1)
905
-					{
906
-						mapn[ix] = ix;
907
-						intNormalsCount++;
908
-					}
909
-			}
910
-		}
911
-				
912
-		// Allocate buffers
913
-		mm[mi]->coordIndex = (int *)malloc((to - from) * sizeof(int));
914
-		mm[mi]->textureIndex = (int *)malloc((to - from) * sizeof(int));
915
-		mm[mi]->normalsIndex = (int *)malloc((to - from) * sizeof(int));
916
-		if (intVertexCount > 0)
917
-			mm[mi]->vertices = (vec3 *)malloc(intVertexCount * sizeof(vec3));
918
-		if (intTexCount > 0)
919
-			mm[mi]->textureCoords = (vec2 *)malloc(intTexCount * sizeof(vec2));
920
-		if (intNormalsCount > 0)
921
-			mm[mi]->vertexNormals = (vec3 *)malloc(intNormalsCount * sizeof(vec3));
922
-		mm[mi]->vertexCount = intVertexCount;
923
-		mm[mi]->texCount = intTexCount;
924
-		mm[mi]->normalsCount = intNormalsCount;
925
-		
926
-		// Fill mapc, mapt, mapn with -1 (illegal index)
927
-		for (int ii = 0; ii < m->vertexCount; ii++)
928
-			mapc[ii] = -1;
929
-		for (int ii = 0; ii < m->texCount; ii++)
930
-			mapt[ii] = -1;
931
-		for (int ii = 0; ii < m->normalsCount; ii++)
932
-			mapn[ii] = -1;
933
-		
934
-		int mapcCount = 0;
935
-		int maptCount = 0;
936
-		int mapnCount = 0;
937
-		for (int j = from; j < to; j++) // For all index triplets
938
-		{
939
-			int ix = m->coordIndex[j];
940
-			if (ix > -1)
941
-			{
942
-				if (mapc[ix] == -1) // Unmapped
943
-				{
944
-					mapc[ix] = mapcCount++;
945
-					mm[mi]->vertices[mapc[ix]] = m->vertices[ix]; // Copy vertex to mm[i]
946
-				}
947
-				mm[mi]->coordIndex[j-from] = mapc[ix];
948
-			}
949
-			else // Separator
950
-			{
951
-				mm[mi]->coordIndex[j-from] = -1;
952
-			}
953
-
954
-			if (m->textureIndex != NULL)
955
-			if (mm[mi]->textureIndex != NULL)
956
-			{
957
-				ix = m->textureIndex[j];
958
-				if (ix > -1)
959
-				{
960
-					if (mapt[ix] == -1) // Unmapped
961
-					{
962
-						mapt[ix] = maptCount++;
963
-						mm[mi]->textureCoords[mapt[ix]] = m->textureCoords[ix]; // Copy vertex to mm[i]
964
-					}
965
-					mm[mi]->textureIndex[j-from] = mapt[ix];
966
-				}
967
-				else // Separator
968
-				{
969
-					mm[mi]->textureIndex[j-from] = -1;
970
-				}
971
-			}
972
-
973
-			if (m->normalsIndex != NULL)
974
-			if (mm[mi]->normalsIndex != NULL)
975
-			{
976
-				ix = m->normalsIndex[j];
977
-				if (ix > -1)
978
-				{
979
-					if (mapn[ix] == -1) // Unmapped
980
-					{
981
-						mapn[ix] = mapnCount++;
982
-						mm[mi]->vertexNormals[mapn[ix]] = m->vertexNormals[ix]; // Copy vertex to mm[i]
983
-					}
984
-					mm[mi]->normalsIndex[j-from] = mapn[ix];
985
-				}
986
-				else // Separator
987
-				{
988
-					mm[mi]->normalsIndex[j-from] = -1;
989
-				}
990
-			}
991
-		} // for all index triplets
992
-		mm[mi]->coordCount = to - from;
993
-		
994
-		if (gMtlNameList != NULL)
995
-		{
996
-			mm[mi]->materialName = gMtlNameList[mi];
997
-			gMtlNameList[mi] = NULL; // No longer "owned" by the gMtlNameList
998
-		}
999
-	} // for all parts
1000
-	
1001
-	return mm;
1002
-}
1003
-
1004
-
1005
-static void DisposeMesh(Mesh *mesh)
1006
-{
1007
-// Free the mesh!
1008
-	if (mesh != NULL)
1009
-	{
1010
-		if (mesh->vertices != NULL)
1011
-			free(mesh->vertices);
1012
-		if (mesh->vertexNormals != NULL)
1013
-			free(mesh->vertexNormals);
1014
-		if (mesh->textureCoords != NULL)
1015
-			free(mesh->textureCoords);
1016
-		if (mesh->coordIndex != NULL)
1017
-			free(mesh->coordIndex);
1018
-		if (mesh->normalsIndex != NULL)
1019
-			free(mesh->normalsIndex);
1020
-		if (mesh->textureIndex != NULL)
1021
-			free(mesh->textureIndex);
1022
-#if !defined(_WIN32)
1023
-// This is very disturbing, causes heap corruption on Windows. Reason not found.
1024
-		if (mesh->coordStarts != NULL)
1025
-			free(mesh->coordStarts);
1026
-#endif
1027
-		if (mesh->materialName != NULL)
1028
-			free(mesh->materialName);
1029
-
1030
-// Dispose the material name list too
1031
-		if (gMtlNameList != NULL)
1032
-		{
1033
-			for (int i = 0; i < mesh->groupCount; i++)
1034
-				if (gMtlNameList[i] != NULL)
1035
-					free(gMtlNameList[i]);
1036
-			free(gMtlNameList);
1037
-			gMtlNameList = NULL;
1038
-		}
1039
-
1040
-		free(mesh);
1041
-	}
1042
-}
1043
-
1044
-void CenterModel(Model *m)
1045
-{
1046
-	int i;
1047
-	float maxx = -1e10, maxy = -1e10, maxz = -1e10, minx = 1e10, miny = 1e10, minz = 1e10;
1048
-	
1049
-	for (i = 0; i < m->numVertices; i++)
1050
-	{
1051
-		if (m->vertexArray[i].x < minx) minx = m->vertexArray[i].x;
1052
-		if (m->vertexArray[i].x > maxx) maxx = m->vertexArray[i].x;
1053
-		if (m->vertexArray[i].y < miny) miny = m->vertexArray[i].y;
1054
-		if (m->vertexArray[i].y > maxy) maxy = m->vertexArray[i].y;
1055
-		if (m->vertexArray[i].z < minz) minz = m->vertexArray[i].z;
1056
-		if (m->vertexArray[i].z > maxz) maxz = m->vertexArray[i].z;
1057
-	}
1058
-	
1059
-	for (i = 0; i < m->numVertices; i++)
1060
-	{
1061
-		m->vertexArray[i].x -= (maxx + minx)/2.0f;
1062
-		m->vertexArray[i].y -= (maxy + miny)/2.0f;
1063
-		m->vertexArray[i].z -= (maxz + minz)/2.0f;
1064
-	}
1065
-}
1066
-
1067
-void ScaleModel(Model *m, float sx, float sy, float sz)
1068
-{
1069
-	long i;
1070
-	for (i = 0; i < m->numVertices; i++)
1071
-	{
1072
-		m->vertexArray[i].x *= sx;
1073
-		m->vertexArray[i].y *= sy;
1074
-		m->vertexArray[i].z *= sz;
1075
-	}
1076
-}
1077
-
1078
-static void ReportRerror(const char *caller, const char *name)
1079
-{
1080
-	static unsigned int draw_error_counter = 0; 
1081
-   if(draw_error_counter < NUM_DRAWMODEL_ERROR)
1082
-   {
1083
-		    fprintf(stderr, "%s warning: '%s' not found in shader!\n", caller, name);
1084
-		    draw_error_counter++;
1085
-   }
1086
-   else if(draw_error_counter == NUM_DRAWMODEL_ERROR)
1087
-   {
1088
-		    fprintf(stderr, "%s: Number of error bigger than %i. No more vill be printed.\n", caller, NUM_DRAWMODEL_ERROR);
1089
-		    draw_error_counter++;
1090
-   }
1091
-}
1092
-
1093
-// This code makes a lot of calls for rebinding variables just in case,
1094
-// and to get attribute locations. This is clearly not optimal, but the
1095
-// goal is stability.
1096
-
1097
-void DrawModel(Model *m, GLuint program, const char* vertexVariableName, const char* normalVariableName, const char* texCoordVariableName)
1098
-{
1099
-	if (m != NULL)
1100
-	{
1101
-		GLint loc;
1102
-		
1103
-		glBindVertexArray(m->vao);	// Select VAO
1104
-
1105
-		glBindBuffer(GL_ARRAY_BUFFER, m->vb);
1106
-		loc = glGetAttribLocation(program, vertexVariableName);
1107
-		if (loc >= 0)
1108
-		{
1109
-			glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); 
1110
-			glEnableVertexAttribArray(loc);
1111
-		}
1112
-		else
1113
-			ReportRerror("DrawModel", vertexVariableName);
1114
-		
1115
-		if (normalVariableName!=NULL)
1116
-		{
1117
-			loc = glGetAttribLocation(program, normalVariableName);
1118
-			if (loc >= 0)
1119
-			{
1120
-				glBindBuffer(GL_ARRAY_BUFFER, m->nb);
1121
-				glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
1122
-				glEnableVertexAttribArray(loc);
1123
-			}
1124
-			else
1125
-				ReportRerror("DrawModel", normalVariableName);
1126
-		}
1127
-	
1128
-		if ((m->texCoordArray != NULL)&&(texCoordVariableName != NULL))
1129
-		{
1130
-			loc = glGetAttribLocation(program, texCoordVariableName);
1131
-			if (loc >= 0)
1132
-			{
1133
-				glBindBuffer(GL_ARRAY_BUFFER, m->tb);
1134
-				glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
1135
-				glEnableVertexAttribArray(loc);
1136
-			}
1137
-			else
1138
-				ReportRerror("DrawModel", texCoordVariableName);
1139
-		}
1140
-
1141
-		glDrawElements(GL_TRIANGLES, m->numIndices, GL_UNSIGNED_INT, 0L);
1142
-	}
1143
-}
1144
-
1145
-void DrawWireframeModel(Model *m, GLuint program, const char* vertexVariableName, const char* normalVariableName, const char* texCoordVariableName)
1146
-{
1147
-	if (m != NULL)
1148
-	{
1149
-		GLint loc;
1150
-		
1151
-		glBindVertexArray(m->vao);	// Select VAO
1152
-
1153
-		glBindBuffer(GL_ARRAY_BUFFER, m->vb);
1154
-		loc = glGetAttribLocation(program, vertexVariableName);
1155
-		if (loc >= 0)
1156
-		{
1157
-			glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); 
1158
-			glEnableVertexAttribArray(loc);
1159
-		}
1160
-		else
1161
-			ReportRerror("DrawWireframeModel", vertexVariableName);
1162
-		
1163
-		if (normalVariableName!=NULL)
1164
-		{
1165
-			loc = glGetAttribLocation(program, normalVariableName);
1166
-			if (loc >= 0)
1167
-			{
1168
-				glBindBuffer(GL_ARRAY_BUFFER, m->nb);
1169
-				glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
1170
-				glEnableVertexAttribArray(loc);
1171
-			}
1172
-			else
1173
-				ReportRerror("DrawWireframeModel", normalVariableName);
1174
-		}
1175
-	
1176
-		if ((m->texCoordArray != NULL)&&(texCoordVariableName != NULL))
1177
-		{
1178
-			loc = glGetAttribLocation(program, texCoordVariableName);
1179
-			if (loc >= 0)
1180
-			{
1181
-				glBindBuffer(GL_ARRAY_BUFFER, m->tb);
1182
-				glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
1183
-				glEnableVertexAttribArray(loc);
1184
-			}
1185
-			else
1186
-				ReportRerror("DrawWireframeModel", texCoordVariableName);
1187
-		}
1188
-		glDrawElements(GL_LINE_STRIP, m->numIndices, GL_UNSIGNED_INT, 0L);
1189
-	}
1190
-}
1191
-	
1192
-// Called from LoadModel, LoadModelSet and LoadDataToModel
1193
-// VAO and VBOs must already exist!
1194
-// Useful by its own when the model changes on CPU
1195
-void ReloadModelData(Model *m)
1196
-{
1197
-	glBindVertexArray(m->vao);
1198
-	
1199
-	// VBO for vertex data
1200
-	glBindBuffer(GL_ARRAY_BUFFER, m->vb);
1201
-	glBufferData(GL_ARRAY_BUFFER, m->numVertices*3*sizeof(GLfloat), m->vertexArray, GL_STATIC_DRAW);
1202
-	
1203
-	// VBO for normal data
1204
-	glBindBuffer(GL_ARRAY_BUFFER, m->nb);
1205
-	glBufferData(GL_ARRAY_BUFFER, m->numVertices*3*sizeof(GLfloat), m->normalArray, GL_STATIC_DRAW);
1206
-	
1207
-	// VBO for texture coordinate data NEW for 5b
1208
-	if (m->texCoordArray != NULL)
1209
-	{
1210
-		glBindBuffer(GL_ARRAY_BUFFER, m->tb);
1211
-		glBufferData(GL_ARRAY_BUFFER, m->numVertices*2*sizeof(GLfloat), m->texCoordArray, GL_STATIC_DRAW);
1212
-	}
1213
-	
1214
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ib);
1215
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER, m->numIndices*sizeof(GLuint), m->indexArray, GL_STATIC_DRAW);
1216
-}
1217
-
1218
-static void GenModelBuffers(Model *m)
1219
-{
1220
-	glGenVertexArrays(1, &m->vao);
1221
-	glGenBuffers(1, &m->vb);
1222
-	glGenBuffers(1, &m->ib);
1223
-	glGenBuffers(1, &m->nb);
1224
-	if (m->texCoordArray != NULL)
1225
-		glGenBuffers(1, &m->tb);
1226
-
1227
-	ReloadModelData(m);
1228
-}
1229
-
1230
-// For simple models
1231
-Model* LoadModel(const char* name)
1232
-{
1233
-	Model* model = NULL;
1234
-	Mesh* mesh = LoadOBJ(name);
1235
-	DecomposeToTriangles(mesh);
1236
-	GenerateNormals(mesh);
1237
-	model = GenerateModel(mesh);
1238
-	DisposeMesh(mesh);
1239
-
1240
-	GenModelBuffers(model);	
1241
-	return model;
1242
-}
1243
-
1244
-// For multiple part models
1245
-Model** LoadModelSet(const char* name)
1246
-{
1247
-	Mesh* mesh = LoadOBJ(name);
1248
-	Mesh **mm = SplitToMeshes(mesh);
1249
-	int i, ii;
1250
-	for (i = 0; mm[i] != NULL; i++) {}
1251
-	Model **md = (Model **)calloc(sizeof(Model *), i+1);
1252
-	for (ii = 0; mm[ii] != NULL; ii++)
1253
-	{
1254
-		DecomposeToTriangles(mm[ii]);
1255
-		GenerateNormals(mm[ii]);
1256
-		md[ii] = GenerateModel(mm[ii]);
1257
-		DisposeMesh(mm[ii]);
1258
-	}
1259
-	free(mm);
1260
-	DisposeMtlList(gMaterials);
1261
-	DisposeMesh(mesh);
1262
-	gMtlNameList = NULL;
1263
-	gMaterials = NULL;
1264
-	
1265
-	for (int i = 0; md[i] != NULL; i++)
1266
-		GenModelBuffers(md[i]);
1267
-
1268
-	return md;
1269
-}
1270
-
1271
-// Loader for inline data to Model (almost same as LoadModelPlus)
1272
-Model* LoadDataToModel(
1273
-			vec3 *vertices,
1274
-			vec3 *normals,
1275
-			vec2 *texCoords,
1276
-			vec3 *colors,
1277
-			GLuint *indices,
1278
-			int numVert,
1279
-			int numInd)
1280
-{
1281
-	Model* m = (Model *)malloc(sizeof(Model));
1282
-	memset(m, 0, sizeof(Model));
1283
-	
1284
-	m->vertexArray = vertices;
1285
-	m->texCoordArray = texCoords;
1286
-	m->normalArray = normals;
1287
-	m->indexArray = indices;
1288
-	m->numVertices = numVert;
1289
-	m->numIndices = numInd;
1290
-	
1291
-	GenModelBuffers(m);
1292
-	
1293
-	return m;
1294
-}
1295
-
1296
-// Cleanup function, not tested!
1297
-void DisposeModel(Model *m)
1298
-{
1299
-	if (m != NULL)
1300
-	{
1301
-		if (m->vertexArray != NULL)
1302
-			free(m->vertexArray);
1303
-		if (m->normalArray != NULL)
1304
-			free(m->normalArray);
1305
-		if (m->texCoordArray != NULL)
1306
-			free(m->texCoordArray);
1307
-		if (m->colorArray != NULL) // obsolete?
1308
-			free(m->colorArray);
1309
-		if (m->indexArray != NULL)
1310
-			free(m->indexArray);
1311
-		
1312
-		// Lazy error checking here since "glDeleteBuffers silently ignores 0's and names that do not correspond to existing buffer objects."
1313
-		glDeleteBuffers(1, &m->vb);
1314
-		glDeleteBuffers(1, &m->ib);
1315
-		glDeleteBuffers(1, &m->nb);
1316
-		glDeleteBuffers(1, &m->tb);
1317
-		glDeleteVertexArrays(1, &m->vao);
1318
-		
1319
-		if (m->material != NULL)
1320
-			free(m->material);
1321
-	}
1322
-	free(m);
1323
-}
... ...
@@ -12,6 +12,8 @@
12 12
 // 180216: calloc is better than malloc when you may have undefined data in parts of the texture!
13 13
 // 190416: Skipped testing the last four bytes of the 12-byte heading. That is the origin of the
14 14
 // image which is usually 0. It is now ignored.
15
+// 220218: Big change: Removed the power of 2. GPUs with that limitation are gone now.
16
+// This simplifies both the code and the interface.
15 17
 
16 18
 // NOTE: LoadTGA does NOT support all TGA variants! You may need to re-save your TGA
17 19
 // with different settings to find a suitable format.
... ...
@@ -43,7 +45,7 @@ bool LoadTGATextureData(const char *filename, TextureData *texture)	// Loads A T
43 45
 		imageSize,		// Used To Store The Image Size When Setting Aside Ram
44 46
 		temp;			// Temporary Variable
45 47
 	long rowSize, stepSize, bytesRead;
46
-	long w, h;
48
+//	long w, h;
47 49
 	GLubyte *rowP;
48 50
 	int err;
49 51
 	GLubyte rle;
... ...
@@ -109,20 +111,21 @@ bool LoadTGATextureData(const char *filename, TextureData *texture)	// Loads A T
109 111
 		return false;
110 112
 	}
111 113
 	flipped = (header[5] & 32) != 0; // Testa om flipped
112
-	
113
-	w = 1;
114
-	while (w < texture->width) w = w << 1;
115
-	h = 1;
116
-	while (h < texture->height) h = h << 1;
117
-	texture->texWidth = (GLfloat)texture->width / w;
118
-	texture->texHeight = (GLfloat)texture->height / h;
114
+
115
+// That old power of 2 is no longer needed!
116
+//	w = 1;
117
+//	while (w < texture->width) w = w << 1;
118
+//	h = 1;
119
+//	while (h < texture->height) h = h << 1;
120
+//	texture->texWidth = (GLfloat)texture->width / w;
121
+//	texture->texHeight = (GLfloat)texture->height / h;
119 122
 	
120 123
 	
121 124
 	texture->bpp = header[4];		// Grab The TGA's Bits Per Pixel (24 or 32)
122 125
 	bytesPerPixel = texture->bpp/8;		// Divide By 8 To Get The Bytes Per Pixel
123
-	imageSize = w * h * bytesPerPixel;	// Calculate The Memory Required For The TGA Data
126
+	imageSize = texture->width * texture->height * bytesPerPixel;	// Calculate The Memory Required For The TGA Data
124 127
 	rowSize	= texture->width * bytesPerPixel;	// Image memory per row
125
-	stepSize = w * bytesPerPixel;		// Memory per row
128
+	stepSize = texture->width * bytesPerPixel;		// Memory per row
126 129
 	texture->imageData = (GLubyte *)calloc(1, imageSize);	// Reserve Memory To Hold The TGA Data
127 130
 	if (texture->imageData == NULL)				// Does The Storage Memory Exist?
128 131
 	{
... ...
@@ -133,7 +136,7 @@ bool LoadTGATextureData(const char *filename, TextureData *texture)	// Loads A T
133 136
 	// Set rowP and step depending on direction
134 137
 	// Inverted this 120131, since a texture came out wrong.
135 138
 	// I am still not sure this is OK.
136
-	if (!flipped)
139
+	if (flipped)
137 140
 	{
138 141
 		step = -stepSize;
139 142
 		rowP = &texture->imageData[imageSize - stepSize];
... ...
@@ -204,8 +207,8 @@ bool LoadTGATextureData(const char *filename, TextureData *texture)	// Loads A T
204 207
 	}
205 208
 	fclose (file);
206 209
 
207
-texture->w = w;
208
-texture->h = h;
210
+//texture->w = w;
211
+//texture->h = h;
209 212
 
210 213
 	return true;				// Texture loading Went Ok, Return True
211 214
 }
... ...
@@ -232,7 +235,7 @@ bool LoadTGATexture(const char *filename, TextureData *texture)	// Loads A TGA F
232 235
 	{
233 236
 		type=GL_RGB;			// If So Set The 'type' To GL_RGB
234 237
 	}
235
-	glTexImage2D(GL_TEXTURE_2D, 0, type, texture->w, texture->h, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
238
+	glTexImage2D(GL_TEXTURE_2D, 0, type, texture->width, texture->height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
236 239
 	
237 240
 	if (gMipmap)
238 241
 	{
... ...
@@ -324,7 +327,8 @@ int SaveDataToTGA(char			*filename,
324 327
 
325 328
 	fclose(file);
326 329
 // release the memory
327
-	free(imageData);
330
+// No, this is the responsability of the host!
331
+//	free(imageData);
328 332
 
329 333
 	return(TGA_OK);
330 334
 }
331 335
deleted file mode 100755
... ...
@@ -1,1125 +0,0 @@
1
-// VectorUtils
2
-// Vector and matrix manipulation library for OpenGL, a package of the most essential functions.
3
-// Includes:
4
-// - Basic vector operations: Add, subtract, scale, dot product, cross product.
5
-// - Basic matrix operations: Multiply matrix to matrix, matric to vector, transpose.
6
-// - Creation of transformation matrixces: Translation, scaling, rotation.
7
-// - A few more special operations: Orthonormalizaton of a matrix, CrossMatrix,
8
-// - Replacements of some GLU functions: lookAt, frustum, perspective.
9
-// - Inverse and inverse transpose for creating normal matrices.
10
-// Supports both C and C++. The C interface makes it accessible from most languages if desired.
11
-
12
-// A note on completeness:
13
-// All operations may not be 100% symmetrical over all types, and some GLSL types are
14
-// missing (like vec2). These will be added if proven important. There is already
15
-// some calls of minor importance (mat3 * mat3, mat3 * vec3) included only for
16
-// symmetry. I don't want the code to grow a lot for such reasons, I want it to be
17
-// compact and to the point.
18
-
19
-// Current open design questions:
20
-// Naming conventions: Lower case or capitalized? (Frustum/frustum)
21
-// Prefix for function calls? (The cost would be more typing and making the code harder to read.)
22
-// Add vector operations for vec4? Other *essential* symmetry issues?
23
-// Names for functions when supporting both vec3 and vec4, mat3 and mat4? (vec3Add, vec4Add?)
24
-
25
-
26
-// History:
27
-
28
-// VectorUtils is a small (but growing) math unit by Ingemar Ragnemalm.
29
-// It originated as "geom3d" by Andrew Meggs, but that unit is no more
30
-// than inspiration today. The original VectorUtils(1) was based on it,
31
-// while VectorUtils2 was a rewrite primarily to get rid of the over-use
32
-// of arrays in the original.
33
-
34
-// New version 120201:
35
-// Defaults to matrices "by the book". Can also be configured to the flipped
36
-// column-wise matrices that old OpenGL required (and we all hated).
37
-// This is freshly implemented, limited testing, so there can be bugs.
38
-// But it seems to work just fine on my tests with translation, rotations
39
-// and matrix multiplications.
40
-
41
-// 1208??: Added lookAt, perspective, frustum
42
-// Also made Transpose do what it should. TransposeRotation is the old function.
43
-// 120913: Fixed perspective. Never trust other's code...
44
-// 120925: Transposing in CrossMatrix
45
-// 121119: Fixed one more glitch in perspective.
46
-
47
-// 130227 First draft to a version 3.
48
-// C++ operators if accessed from C++
49
-// Vectors by value when possible. Return values on the stack.
50
-// (Why was this not the case in VectorUtils2? Beause I tried to stay compatible
51
-// with an old C compiler. Older C code generally prefers all non-scalar data by
52
-// reference. But I'd like to move away from that now.)
53
-// Types conform with GLSL as much as possible (vec3, mat4)
54
-// Added some operations for mat3 and vec4, but most of them are more for
55
-// completeness than usefulness; I find vec3's and mat4's to be what I use
56
-// most of the time.
57
-// Also added InvertMat3 and InversTranspose to support creation of normal matrices.
58
-// Marked some calls for removal: CopyVector, TransposeRotation, CopyMatrix.
59
-// 130308: Added InvertMat4 and some more vec3/vec4 operators (+= etc)
60
-// 130922: Fixed a vital bug in CrossMatrix.
61
-// 130924: Fixed a bug in mat3tomat4.
62
-// 131014: Added TransposeMat3 (although I doubt its importance)
63
-// 140213: Corrected mat3tomat4. (Were did the correction in 130924 go?)
64
-// 151210: Added printMat4 and printVec3.
65
-// 160302: Added empty constructors for vec3 and vec4.
66
-// 170221: Uses _WIN32 instead of WIN32
67
-// 170331: Added stdio.h for printMat4 and printVec3
68
-// 180314: Added some #defines for moving closer to GLSL (dot, cross...).
69
-// 2021-05-15: Constructiors for vec3 etc replaced in order to avoid
70
-// problems with some C++ compilers.
71
-// 2022-05-14: Corrected transposed version of lookAtv.
72
-// 2023-01-31: Added shader upload utility functions.
73
-
74
-// You may use VectorUtils as you please. A reference to the origin is appreciated
75
-// but if you grab some snippets from it without reference... no problem.
76
-
77
-
78
-#include "VectorUtils3.h"
79
-
80
-// VS doesn't define NAN properly
81
-#ifdef _WIN32
82
-    #ifndef NAN
83
-        static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
84
-        #define NAN (*(const float *) __nan)
85
-    #endif
86
-#endif
87
-
88
-char transposed = 0;
89
-
90
-	vec3 SetVector(GLfloat x, GLfloat y, GLfloat z)
91
-	{
92
-		vec3 v;
93
-		
94
-		v.x = x;
95
-		v.y = y;
96
-		v.z = z;
97
-		return v;
98
-	}
99
-
100
-// New better name
101
-	vec2 SetVec2(GLfloat x, GLfloat y)
102
-	{
103
-		vec2 v;
104
-		
105
-		v.x = x;
106
-		v.y = y;
107
-		return v;
108
-	}
109
-
110
-	vec3 SetVec3(GLfloat x, GLfloat y, GLfloat z)
111
-	{
112
-		vec3 v;
113
-		
114
-		v.x = x;
115
-		v.y = y;
116
-		v.z = z;
117
-		return v;
118
-	}
119
-
120
-	vec4 SetVec4(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
121
-	{
122
-		vec4 v;
123
-		
124
-		v.x = x;
125
-		v.y = y;
126
-		v.z = z;
127
-		v.w = w;
128
-		return v;
129
-	}
130
-
131
-// Modern C doesn't need this, but Visual Studio insists on old-fashioned C and needs this.
132
-	mat3 SetMat3(GLfloat p0, GLfloat p1, GLfloat p2, GLfloat p3, GLfloat p4, GLfloat p5, GLfloat p6, GLfloat p7, GLfloat p8)
133
-	{
134
-		mat3 m;
135
-		m.m[0] = p0;
136
-		m.m[1] = p1;
137
-		m.m[2] = p2;
138
-		m.m[3] = p3;
139
-		m.m[4] = p4;
140
-		m.m[5] = p5;
141
-		m.m[6] = p6;
142
-		m.m[7] = p7;
143
-		m.m[8] = p8;
144
-		return m;
145
-	}
146
-
147
-// Like above; Modern C doesn't need this, but Visual Studio insists on old-fashioned C and needs this.
148
-	mat4 SetMat4(GLfloat p0, GLfloat p1, GLfloat p2, GLfloat p3,
149
-				GLfloat p4, GLfloat p5, GLfloat p6, GLfloat p7,
150
-				GLfloat p8, GLfloat p9, GLfloat p10, GLfloat p11, 
151
-				GLfloat p12, GLfloat p13, GLfloat p14, GLfloat p15
152
-				)
153
-	{
154
-		mat4 m;
155
-		m.m[0] = p0;
156
-		m.m[1] = p1;
157
-		m.m[2] = p2;
158
-		m.m[3] = p3;
159
-		m.m[4] = p4;
160
-		m.m[5] = p5;
161
-		m.m[6] = p6;
162
-		m.m[7] = p7;
163
-		m.m[8] = p8;
164
-		m.m[9] = p9;
165
-		m.m[10] = p10;
166
-		m.m[11] = p11;
167
-		m.m[12] = p12;
168
-		m.m[13] = p13;
169
-		m.m[14] = p14;
170
-		m.m[15] = p15;
171
-		return m;
172
-	}
173
-
174
-
175
-	// vec3 operations
176
-	// vec4 operations can easily be added but I havn't seen much need for them.
177
-	// Some are defined as C++ operators though.
178
-
179
-	vec3 VectorSub(vec3 a, vec3 b)
180
-	{
181
-		vec3 result;
182
-		
183
-		result.x = a.x - b.x;
184
-		result.y = a.y - b.y;
185
-		result.z = a.z - b.z;
186
-		return result;
187
-	}
188
-	
189
-	vec3 VectorAdd(vec3 a, vec3 b)
190
-	{
191
-		vec3 result;
192
-		
193
-		result.x = a.x + b.x;
194
-		result.y = a.y + b.y;
195
-		result.z = a.z + b.z;
196
-		return result;
197
-	}
198
-
199
-	vec3 CrossProduct(vec3 a, vec3 b)
200
-	{
201
-		vec3 result;
202
-
203
-		result.x = a.y*b.z - a.z*b.y;
204
-		result.y = a.z*b.x - a.x*b.z;
205
-		result.z = a.x*b.y - a.y*b.x;
206
-		
207
-		return result;
208
-	}
209
-
210
-	GLfloat DotProduct(vec3 a, vec3 b)
211
-	{
212
-		return a.x * b.x + a.y * b.y + a.z * b.z;
213
-	}
214
-
215
-	vec3 ScalarMult(vec3 a, GLfloat s)
216
-	{
217
-		vec3 result;
218
-		
219
-		result.x = a.x * s;
220
-		result.y = a.y * s;
221
-		result.z = a.z * s;
222
-		
223
-		return result;
224
-	}
225
-
226
-	GLfloat Norm(vec3 a)
227
-	{
228
-		GLfloat result;
229
-
230
-		result = (GLfloat)sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
231
-		return result;
232
-	}
233
-
234
-	vec3 Normalize(vec3 a)
235
-	{
236
-		GLfloat norm;
237
-		vec3 result;
238
-
239
-		norm = (GLfloat)sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
240
-		result.x = a.x / norm;
241
-		result.y = a.y / norm;
242
-		result.z = a.z / norm;
243
-		return result;
244
-	}
245
-
246
-	vec3 CalcNormalVector(vec3 a, vec3 b, vec3 c)
247
-	{
248
-		vec3 n;
249
-
250
-		n = CrossProduct(VectorSub(a, b), VectorSub(a, c));
251
-		n = ScalarMult(n, 1/Norm(n));
252
-		
253
-		return n;
254
-	}
255
-
256
-// Splits v into vn (parallell to n) and vp (perpendicular). Does not demand n to be normalized.
257
-	void SplitVector(vec3 v, vec3 n, vec3 *vn, vec3 *vp)
258
-	{
259
-		GLfloat nlen;
260
-		GLfloat nlen2;
261
-
262
-		nlen = DotProduct(v, n);
263
-		nlen2 = n.x*n.x+n.y*n.y+n.z*n.z; // Squared length
264
-		if (nlen2 == 0)
265
-		{
266
-			*vp = v;
267
-			*vn = SetVector(0, 0, 0);
268
-		}
269
-		else
270
-		{
271
-			*vn = ScalarMult(n, nlen/nlen2);
272
-			*vp = VectorSub(v, *vn);
273
-		}
274
-	}
275
-
276
-// Matrix operations primarily on 4x4 matrixes!
277
-// Row-wise by default but can be configured to column-wise (see SetTransposed)
278
-
279
-	mat4 IdentityMatrix()
280
-	{
281
-		mat4 m;
282
-		int i;
283
-
284
-		for (i = 0; i <= 15; i++)
285
-			m.m[i] = 0;
286
-		for (i = 0; i <= 3; i++)
287
-			m.m[i * 5] = 1; // 0,5,10,15
288
-		return m;
289
-	}
290
-
291
-	mat4 Rx(GLfloat a)
292
-	{
293
-		mat4 m;
294
-		m = IdentityMatrix();
295
-		m.m[5] = (GLfloat)cos(a);
296
-		if (transposed)
297
-			m.m[9] = (GLfloat)-sin(a);
298
-		else
299
-			m.m[9] = (GLfloat)sin(a);
300
-		m.m[6] = -m.m[9]; //sin(a);
301
-		m.m[10] = m.m[5]; //cos(a);
302
-		return m;
303
-	}
304
-
305
-	mat4 Ry(GLfloat a)
306
-	{
307
-		mat4 m;
308
-		m = IdentityMatrix();
309
-		m.m[0] = (GLfloat)cos(a);
310
-		if (transposed)
311
-			m.m[8] = (GLfloat)sin(a); // Was flipped
312
-		else
313
-			m.m[8] = (GLfloat)-sin(a);
314
-		m.m[2] = -m.m[8]; //sin(a);
315
-		m.m[10] = m.m[0]; //cos(a);
316
-		return m;
317
-	}
318
-
319
-	mat4 Rz(GLfloat a)
320
-	{
321
-		mat4 m;
322
-		m = IdentityMatrix();
323
-		m.m[0] = (GLfloat)cos(a);
324
-		if (transposed)
325
-			m.m[4] = (GLfloat)-sin(a);
326
-		else
327
-			m.m[4] = (GLfloat)sin(a);
328
-		m.m[1] = -m.m[4]; //sin(a);
329
-		m.m[5] = m.m[0]; //cos(a);
330
-		return m;
331
-	}
332
-
333
-	mat4 T(GLfloat tx, GLfloat ty, GLfloat tz)
334
-	{
335
-		mat4 m;
336
-		m = IdentityMatrix();
337
-		if (transposed)
338
-		{
339
-			m.m[12] = tx;
340
-			m.m[13] = ty;
341
-			m.m[14] = tz;
342
-		}
343
-		else
344
-		{
345
-			m.m[3] = tx;
346
-			m.m[7] = ty;
347
-			m.m[11] = tz;
348
-		}
349
-		return m;
350
-	}
351
-
352
-	mat4 S(GLfloat sx, GLfloat sy, GLfloat sz)
353
-	{
354
-		mat4 m;
355
-		m = IdentityMatrix();
356
-		m.m[0] = sx;
357
-		m.m[5] = sy;
358
-		m.m[10] = sz;
359
-		return m;
360
-	}
361
-
362
-	mat4 Mult(mat4 a, mat4 b) // m = a * b
363
-	{
364
-		mat4 m;
365
-
366
-		int x, y;
367
-		for (x = 0; x <= 3; x++)
368
-			for (y = 0; y <= 3; y++)
369
-				if (transposed)
370
-					m.m[x*4 + y] =	a.m[y+4*0] * b.m[0+4*x] +
371
-								a.m[y+4*1] * b.m[1+4*x] +
372
-								a.m[y+4*2] * b.m[2+4*x] +
373
-								a.m[y+4*3] * b.m[3+4*x];
374
-				else
375
-					m.m[y*4 + x] =	a.m[y*4+0] * b.m[0*4+x] +
376
-								a.m[y*4+1] * b.m[1*4+x] +
377
-								a.m[y*4+2] * b.m[2*4+x] +
378
-								a.m[y*4+3] * b.m[3*4+x];
379
-
380
-		return m;
381
-	}
382
-
383
-	// Ej testad!
384
-	mat3 MultMat3(mat3 a, mat3 b) // m = a * b
385
-	{
386
-		mat3 m;
387
-
388
-		int x, y;
389
-		for (x = 0; x <= 2; x++)
390
-			for (y = 0; y <= 2; y++)
391
-				if (transposed)
392
-					m.m[x*3 + y] =	a.m[y+3*0] * b.m[0+3*x] +
393
-								a.m[y+3*1] * b.m[1+3*x] +
394
-								a.m[y+3*2] * b.m[2+3*x];
395
-				else
396
-					m.m[y*3 + x] =	a.m[y*3+0] * b.m[0*3+x] +
397
-								a.m[y*3+1] * b.m[1*3+x] +
398
-								a.m[y*3+2] * b.m[2*3+x];
399
-
400
-		return m;
401
-	}
402
-
403
-	// mat4 * vec3
404
-	// The missing homogenous coordinate is implicitly set to 1.
405
-	vec3 MultVec3(mat4 a, vec3 b) // result = a * b
406
-	{
407
-		vec3 r;
408
-
409
-		if (!transposed)
410
-		{
411
-			r.x = a.m[0]*b.x + a.m[1]*b.y + a.m[2]*b.z + a.m[3];
412
-			r.y = a.m[4]*b.x + a.m[5]*b.y + a.m[6]*b.z + a.m[7];
413
-			r.z = a.m[8]*b.x + a.m[9]*b.y + a.m[10]*b.z + a.m[11];
414
-		}
415
-		else
416
-		{
417
-			r.x = a.m[0]*b.x + a.m[4]*b.y + a.m[8]*b.z + a.m[12];
418
-			r.y = a.m[1]*b.x + a.m[5]*b.y + a.m[9]*b.z + a.m[13];
419
-			r.z = a.m[2]*b.x + a.m[6]*b.y + a.m[10]*b.z + a.m[14];
420
-		}
421
-
422
-		return r;
423
-	}
424
-
425
-	// mat3 * vec3
426
-	vec3 MultMat3Vec3(mat3 a, vec3 b) // result = a * b
427
-	{
428
-		vec3 r;
429
-		
430
-		if (!transposed)
431
-		{
432
-			r.x = a.m[0]*b.x + a.m[1]*b.y + a.m[2]*b.z;
433
-			r.y = a.m[3]*b.x + a.m[4]*b.y + a.m[5]*b.z;
434
-			r.z = a.m[6]*b.x + a.m[7]*b.y + a.m[8]*b.z;
435
-		}
436
-		else
437
-		{
438
-			r.x = a.m[0]*b.x + a.m[3]*b.y + a.m[6]*b.z;
439
-			r.y = a.m[1]*b.x + a.m[4]*b.y + a.m[7]*b.z;
440
-			r.z = a.m[2]*b.x + a.m[5]*b.y + a.m[8]*b.z;
441
-		}
442
-		
443
-		return r;
444
-	}
445
-
446
-	// mat4 * vec4
447
-	vec4 MultVec4(mat4 a, vec4 b) // result = a * b
448
-	{
449
-		vec4 r;
450
-
451
-		if (!transposed)
452
-		{
453
-			r.x = a.m[0]*b.x + a.m[1]*b.y + a.m[2]*b.z + a.m[3]*b.w;
454
-			r.y = a.m[4]*b.x + a.m[5]*b.y + a.m[6]*b.z + a.m[7]*b.w;
455
-			r.z = a.m[8]*b.x + a.m[9]*b.y + a.m[10]*b.z + a.m[11]*b.w;
456
-			r.w = a.m[12]*b.x + a.m[13]*b.y + a.m[14]*b.z + a.m[15]*b.w;
457
-		}
458
-		else
459
-		{
460
-			r.x = a.m[0]*b.x + a.m[4]*b.y + a.m[8]*b.z + a.m[12]*b.w;
461
-			r.y = a.m[1]*b.x + a.m[5]*b.y + a.m[9]*b.z + a.m[13]*b.w;
462
-			r.z = a.m[2]*b.x + a.m[6]*b.y + a.m[10]*b.z + a.m[14]*b.w;
463
-			r.w = a.m[3]*b.x + a.m[7]*b.y + a.m[11]*b.z + a.m[15]*b.w;
464
-		}
465
-
466
-		return r;
467
-	}
468
-
469
-
470
-// Unnecessary
471
-// Will probably be removed
472
-//	void CopyMatrix(GLfloat *src, GLfloat *dest)
473
-//	{
474
-//		int i;
475
-//		for (i = 0; i <= 15; i++)
476
-//			dest[i] = src[i];
477
-//	}
478
-
479
-
480
-// Added for lab 3 (TSBK03)
481
-
482
-	// Orthonormalization of Matrix4D. Assumes rotation only, translation/projection ignored
483
-	void OrthoNormalizeMatrix(mat4 *R)
484
-	{
485
-		vec3 x, y, z;
486
-
487
-		if (transposed)
488
-		{
489
-			x = SetVector(R->m[0], R->m[1], R->m[2]);
490
-			y = SetVector(R->m[4], R->m[5], R->m[6]);
491
-//		SetVector(R[8], R[9], R[10], &z);
492
-			// Kryssa fram ur varandra
493
-			// Normera
494
-			z = CrossProduct(x, y);
495
-			z = Normalize(z);
496
-			x = Normalize(x);
497
-			y = CrossProduct(z, x);
498
-			R->m[0] = x.x;
499
-			R->m[1] = x.y;
500
-			R->m[2] = x.z;
501
-			R->m[4] = y.x;
502
-			R->m[5] = y.y;
503
-			R->m[6] = y.z;
504
-			R->m[8] = z.x;
505
-			R->m[9] = z.y;
506
-			R->m[10] = z.z;
507
-
508
-			R->m[3] = 0.0;
509
-			R->m[7] = 0.0;
510
-			R->m[11] = 0.0;
511
-			R->m[12] = 0.0;
512
-			R->m[13] = 0.0;
513
-			R->m[14] = 0.0;
514
-			R->m[15] = 1.0;
515
-		}
516
-		else
517
-		{
518
-		// NOT TESTED
519
-			x = SetVector(R->m[0], R->m[4], R->m[8]);
520
-			y = SetVector(R->m[1], R->m[5], R->m[9]);
521
-//		SetVector(R[2], R[6], R[10], &z);
522
-			// Kryssa fram ur varandra
523
-			// Normera
524
-			z = CrossProduct(x, y);
525
-			z = Normalize(z);
526
-			x = Normalize(x);
527
-			y = CrossProduct(z, x);
528
-			R->m[0] = x.x;
529
-			R->m[4] = x.y;
530
-			R->m[8] = x.z;
531
-			R->m[1] = y.x;
532
-			R->m[5] = y.y;
533
-			R->m[9] = y.z;
534
-			R->m[2] = z.x;
535
-			R->m[6] = z.y;
536
-			R->m[10] = z.z;
537
-
538
-			R->m[3] = 0.0;
539
-			R->m[7] = 0.0;
540
-			R->m[11] = 0.0;
541
-			R->m[12] = 0.0;
542
-			R->m[13] = 0.0;
543
-			R->m[14] = 0.0;
544
-			R->m[15] = 1.0;
545
-		}
546
-	}
547
-
548
-
549
-// Commented out since I plan to remove it if I can't see a good reason to keep it.
550
-//	// Only transposes rotation part.
551
-//	mat4 TransposeRotation(mat4 m)
552
-//	{
553
-//		mat4 a;
554
-//		
555
-//		a.m[0] = m.m[0]; a.m[4] = m.m[1]; a.m[8] = m.m[2];      a.m[12] = m.m[12];
556
-//		a.m[1] = m.m[4]; a.m[5] = m.m[5]; a.m[9] = m.m[6];      a.m[13] = m.m[13];
557
-//		a.m[2] = m.m[8]; a.m[6] = m.m[9]; a.m[10] = m.m[10];    a.m[14] = m.m[14];
558
-//		a.m[3] = m.m[3]; a.m[7] = m.m[7]; a.m[11] = m.m[11];    a.m[15] = m.m[15];
559
-//		
560
-//		return a;
561
-//	}
562
-
563
-	// Complete transpose!
564
-	mat4 transpose(mat4 m)
565
-	{
566
-		mat4 a;
567
-		
568
-		a.m[0] = m.m[0]; a.m[4] = m.m[1]; a.m[8] = m.m[2];      a.m[12] = m.m[3];
569
-		a.m[1] = m.m[4]; a.m[5] = m.m[5]; a.m[9] = m.m[6];      a.m[13] = m.m[7];
570
-		a.m[2] = m.m[8]; a.m[6] = m.m[9]; a.m[10] = m.m[10];    a.m[14] = m.m[11];
571
-		a.m[3] = m.m[12]; a.m[7] = m.m[13]; a.m[11] = m.m[14];    a.m[15] = m.m[15];
572
-		
573
-		return a;
574
-	}
575
-
576
-	// Complete transpose!
577
-	mat3 TransposeMat3(mat3 m)
578
-	{
579
-		mat3 a;
580
-		
581
-		a.m[0] = m.m[0]; a.m[3] = m.m[1]; a.m[6] = m.m[2];
582
-		a.m[1] = m.m[3]; a.m[4] = m.m[4]; a.m[7] = m.m[5];
583
-		a.m[2] = m.m[6]; a.m[5] = m.m[7]; a.m[8] = m.m[8];
584
-		
585
-		return a;
586
-	}
587
-
588
-// Rotation around arbitrary axis (rotation only)
589
-mat4 ArbRotate(vec3 axis, GLfloat fi)
590
-{
591
-	vec3 x, y, z;
592
-	mat4 R, Rt, Raxel, m;
593
-
594
-// Check if parallel to Z
595
-	if (axis.x < 0.0000001) // Below some small value
596
-	if (axis.x > -0.0000001)
597
-	if (axis.y < 0.0000001)
598
-	if (axis.y > -0.0000001)
599
-	{
600
-		if (axis.z > 0)
601
-		{
602
-			m = Rz(fi);
603
-			return m;
604
-		}
605
-		else
606
-		{
607
-			m = Rz(-fi);
608
-			return m;
609
-		}
610
-	}
611
-
612
-	x = Normalize(axis);
613
-	z = SetVector(0,0,1); // Temp z
614
-	y = Normalize(CrossProduct(z, x)); // y' = z^ x x'
615
-	z = CrossProduct(x, y); // z' = x x y
616
-
617
-	if (transposed)
618
-	{
619
-		R.m[0] = x.x; R.m[4] = x.y; R.m[8] = x.z;  R.m[12] = 0.0;
620
-		R.m[1] = y.x; R.m[5] = y.y; R.m[9] = y.z;  R.m[13] = 0.0;
621
-		R.m[2] = z.x; R.m[6] = z.y; R.m[10] = z.z;  R.m[14] = 0.0;
622
-
623
-		R.m[3] = 0.0; R.m[7] = 0.0; R.m[11] = 0.0;  R.m[15] = 1.0;
624
-	}
625
-	else
626
-	{
627
-		R.m[0] = x.x; R.m[1] = x.y; R.m[2] = x.z;  R.m[3] = 0.0;
628
-		R.m[4] = y.x; R.m[5] = y.y; R.m[6] = y.z;  R.m[7] = 0.0;
629
-		R.m[8] = z.x; R.m[9] = z.y; R.m[10] = z.z;  R.m[11] = 0.0;
630
-
631
-		R.m[12] = 0.0; R.m[13] = 0.0; R.m[14] = 0.0;  R.m[15] = 1.0;
632
-	}
633
-
634
-	Rt = transpose(R); // Transpose = Invert -> felet ej i Transpose, och det �r en ortonormal matris
635
-
636
-	Raxel = Rx(fi); // Rotate around x axis
637
-
638
-	// m := Rt * Rx * R
639
-	m = Mult(Mult(Rt, Raxel), R);
640
-	
641
-	return m;
642
-}
643
-
644
-
645
-// Not tested much
646
-mat4 CrossMatrix(vec3 a) // Matrix for cross product
647
-{
648
-	mat4 m;
649
-	
650
-	if (transposed)
651
-	{
652
-		m.m[0] =    0; m.m[4] =-a.z; m.m[8] = a.y; m.m[12] = 0.0;
653
-		m.m[1] = a.z; m.m[5] =    0; m.m[9] =-a.x; m.m[13] = 0.0;
654
-		m.m[2] =-a.y; m.m[6] = a.x; m.m[10]=    0; m.m[14] = 0.0;
655
-		m.m[3] =  0.0; m.m[7] =  0.0; m.m[11]=  0.0; m.m[15] = 0.0;
656
-		// NOTE! 0.0 in the homogous coordinate. Thus, the matrix can
657
-		// not be generally used, but is fine for matrix differentials
658
-	}
659
-	else
660
-	{
661
-		m.m[0] =    0; m.m[1] =-a.z; m.m[2] = a.y; m.m[3] = 0.0;
662
-		m.m[4] = a.z; m.m[5] =    0; m.m[6] =-a.x; m.m[7] = 0.0;
663
-		m.m[8] =-a.y; m.m[9] = a.x; m.m[10]=    0; m.m[11] = 0.0;
664
-		m.m[12] =  0.0; m.m[13] =  0.0; m.m[14]=  0.0; m.m[15] = 0.0;
665
-		// NOTE! 0.0 in the homogous coordinate. Thus, the matrix can
666
-		// not be generally used, but is fine for matrix differentials
667
-	}
668
-	
669
-	return m;
670
-}
671
-
672
-mat4 MatrixAdd(mat4 a, mat4 b)
673
-{
674
-	mat4 dest;
675
-	
676
-	int i;
677
-	for (i = 0; i < 16; i++)
678
-		dest.m[i] = a.m[i] + b.m[i];
679
-	
680
-	return dest;
681
-}
682
-
683
-
684
-void SetTransposed(char t)
685
-{
686
-	transposed = t;
687
-}
688
-
689
-
690
-// Build standard matrices
691
-
692
-mat4 lookAtv(vec3 p, vec3 l, vec3 v)
693
-{
694
-	vec3 n, u;
695
-	mat4 rot, trans;
696
-
697
-	n = Normalize(VectorSub(p, l));
698
-	u = Normalize(CrossProduct(v, n));
699
-	v = CrossProduct(n, u);
700
-
701
-//	rot = {{ u.x, u.y, u.z, 0,
702
-//                      v.x, v.y, v.z, 0,
703
-//                      n.x, n.y, n.z, 0,
704
-//                      0,   0,   0,   1 }};
705
-// VS friendly version:
706
-	if (transposed)
707
-	rot = SetMat4(u.x, v.x, n.x, 0,
708
-                  u.y, v.y, n.y, 0,
709
-                  u.z, v.z, n.z, 0,
710
-                  0,   0,   0,   1);
711
-	else
712
-	rot = SetMat4(u.x, u.y, u.z, 0,
713
-                  v.x, v.y, v.z, 0,
714
-                  n.x, n.y, n.z, 0,
715
-                  0,   0,   0,   1);
716
-	trans = T(-p.x, -p.y, -p.z);
717
-	return Mult(rot, trans);
718
-}
719
-
720
-mat4 lookAt(GLfloat px, GLfloat py, GLfloat pz, 
721
-			GLfloat lx, GLfloat ly, GLfloat lz,
722
-			GLfloat vx, GLfloat vy, GLfloat vz)
723
-{
724
-	vec3 p, l, v;
725
-	
726
-	p = SetVector(px, py, pz);
727
-	l = SetVector(lx, ly, lz);
728
-	v = SetVector(vx, vy, vz);
729
-	
730
-	return lookAtv(p, l, v);
731
-}
732
-
733
-// From http://www.opengl.org/wiki/GluPerspective_code
734
-// Changed names and parameter order to conform with VU style
735
-// Rewritten 120913 because it was all wrong...
736
-
737
-// Creates a projection matrix like gluPerspective or glFrustum.
738
-// Upload to your shader as usual.
739
-// 2022: Yet another fix. Was it correct this time?
740
-mat4 perspective(float fovyInDegrees, float aspectRatio,
741
-                      float znear, float zfar)
742
-{
743
-	float f = 1.0/tan(fovyInDegrees * M_PI / 360.0);
744
-	mat4 m = SetMat4(f/aspectRatio, 0, 0, 0,
745
-					0, f, 0, 0,
746
-					0, 0, (zfar+znear)/(znear-zfar), 2*zfar*znear/(znear-zfar),
747
-					0, 0, -1, 0);
748
-	if (transposed)
749
-		m = transpose(m);
750
-	return m;
751
-}
752
-
753
-mat4 frustum(float left, float right, float bottom, float top,
754
-                  float znear, float zfar)
755
-{
756
-    float temp, temp2, temp3, temp4;
757
-    mat4 matrix;
758
-    
759
-    temp = 2.0f * znear;
760
-    temp2 = right - left;
761
-    temp3 = top - bottom;
762
-    temp4 = zfar - znear;
763
-    matrix.m[0] = temp / temp2; // 2*near/(right-left)
764
-    matrix.m[1] = 0.0;
765
-    matrix.m[2] = 0.0;
766
-    matrix.m[3] = 0.0;
767
-    matrix.m[4] = 0.0;
768
-    matrix.m[5] = temp / temp3; // 2*near/(top - bottom)
769
-    matrix.m[6] = 0.0;
770
-    matrix.m[7] = 0.0;
771
-    matrix.m[8] = (right + left) / temp2; // A = r+l / r-l
772
-    matrix.m[9] = (top + bottom) / temp3; // B = t+b / t-b
773
-    matrix.m[10] = (-zfar - znear) / temp4; // C = -(f+n) / f-n
774
-    matrix.m[11] = -1.0;
775
-    matrix.m[12] = 0.0;
776
-    matrix.m[13] = 0.0;
777
-    matrix.m[14] = (-temp * zfar) / temp4; // D = -2fn / f-n
778
-    matrix.m[15] = 0.0;
779
-    
780
-    if (!transposed)
781
-    	matrix = transpose(matrix);
782
-    
783
-    return matrix;
784
-}
785
-
786
-// Not tested!
787
-mat4 ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)
788
-{
789
-        float a = 2.0f / (right - left);
790
-        float b = 2.0f / (top - bottom);
791
-        float c = -2.0f / (far - near);
792
-
793
-        float tx = - (right + left)/(right - left);
794
-        float ty = - (top + bottom)/(top - bottom);
795
-        float tz = - (far + near)/(far - near);
796
-
797
-        mat4 o = SetMat4(
798
-            a, 0, 0, tx,
799
-            0, b, 0, ty,
800
-            0, 0, c, tz,
801
-            0, 0, 0, 1);
802
-        return o;
803
-}
804
-
805
-// The code below is based on code from:
806
-// http://www.dr-lex.be/random/matrix_inv.html
807
-
808
-// Inverts mat3 (row-wise matrix)
809
-// (For a more general inverse, try a gaussian elimination.)
810
-mat3 InvertMat3(mat3 in)
811
-{
812
-	float a11, a12, a13, a21, a22, a23, a31, a32, a33;
813
-	mat3 out, nanout;
814
-	float DET;
815
-	
816
-	// Copying to internal variables both clarify the code and
817
-	// buffers data so the output may be identical to the input!
818
-	a11 = in.m[0];
819
-	a12 = in.m[1];
820
-	a13 = in.m[2];
821
-	a21 = in.m[3];
822
-	a22 = in.m[4];
823
-	a23 = in.m[5];
824
-	a31 = in.m[6];
825
-	a32 = in.m[7];
826
-	a33 = in.m[8];
827
-	DET = a11*(a33*a22-a32*a23)-a21*(a33*a12-a32*a13)+a31*(a23*a12-a22*a13);
828
-	if (DET != 0)
829
-	{
830
-		out.m[0] = (a33*a22-a32*a23)/DET;
831
-		out.m[1] = -(a33*a12-a32*a13)/DET;
832
-		out.m[2] = (a23*a12-a22*a13)/DET;
833
-		out.m[3] = -(a33*a21-a31*a23)/DET;
834
-		out.m[4] = (a33*a11-a31*a13)/DET;
835
-		out.m[5] = -(a23*a11-a21*a13)/DET;
836
-		out.m[6] = (a32*a21-a31*a22)/DET;
837
-		out.m[7] = -(a32*a11-a31*a12)/DET;
838
-		out.m[8] = (a22*a11-a21*a12)/DET;
839
-	}
840
-	else
841
-	{
842
-		nanout = SetMat3(NAN, NAN, NAN,
843
-								NAN, NAN, NAN,
844
-								NAN, NAN, NAN);
845
-		out = nanout;
846
-	}
847
-	
848
-	return out;
849
-}
850
-
851
-// For making a normal matrix from a model-to-view matrix
852
-// Takes a mat4 in, ignores 4th row/column (should just be translations),
853
-// inverts as mat3 (row-wise matrix) and returns the transpose
854
-mat3 InverseTranspose(mat4 in)
855
-{
856
-	float a11, a12, a13, a21, a22, a23, a31, a32, a33;
857
-	mat3 out, nanout;
858
-	float DET;
859
-	
860
-	// Copying to internal variables
861
-	a11 = in.m[0];
862
-	a12 = in.m[1];
863
-	a13 = in.m[2];
864
-	a21 = in.m[4];
865
-	a22 = in.m[5];
866
-	a23 = in.m[6];
867
-	a31 = in.m[8];
868
-	a32 = in.m[9];
869
-	a33 = in.m[10];
870
-	DET = a11*(a33*a22-a32*a23)-a21*(a33*a12-a32*a13)+a31*(a23*a12-a22*a13);
871
-	if (DET != 0)
872
-	{
873
-		out.m[0] = (a33*a22-a32*a23)/DET;
874
-		out.m[3] = -(a33*a12-a32*a13)/DET;
875
-		out.m[6] = (a23*a12-a22*a13)/DET;
876
-		out.m[1] = -(a33*a21-a31*a23)/DET;
877
-		out.m[4] = (a33*a11-a31*a13)/DET;
878
-		out.m[7] = -(a23*a11-a21*a13)/DET;
879
-		out.m[2] = (a32*a21-a31*a22)/DET;
880
-		out.m[5] = -(a32*a11-a31*a12)/DET;
881
-		out.m[8] = (a22*a11-a21*a12)/DET;
882
-	}
883
-	else
884
-	{
885
-		nanout = SetMat3(NAN, NAN, NAN,
886
-								NAN, NAN, NAN,
887
-								NAN, NAN, NAN);
888
-		out = nanout;
889
-	}
890
-
891
-	return out;
892
-}
893
-
894
-
895
-// Simple conversions
896
-mat3 mat4tomat3(mat4 m)
897
-{
898
-	mat3 result;
899
-	
900
-	result.m[0] = m.m[0];
901
-	result.m[1] = m.m[1];
902
-	result.m[2] = m.m[2];
903
-	result.m[3] = m.m[4];
904
-	result.m[4] = m.m[5];
905
-	result.m[5] = m.m[6];
906
-	result.m[6] = m.m[8];
907
-	result.m[7] = m.m[9];
908
-	result.m[8] = m.m[10];
909
-	return result;
910
-}
911
-
912
-mat4 mat3tomat4(mat3 m)
913
-{
914
-	mat4 result;
915
-	
916
-	result.m[0] = m.m[0];
917
-	result.m[1] = m.m[1];
918
-	result.m[2] = m.m[2];
919
-	result.m[3] = 0;
920
-	result.m[4] = m.m[3];
921
-	result.m[5] = m.m[4];
922
-	result.m[6] = m.m[5];
923
-	result.m[7] = 0;
924
-	result.m[8] = m.m[6];
925
-	result.m[9] = m.m[7];
926
-	result.m[10] = m.m[8];
927
-	result.m[11] = 0;
928
-
929
-	result.m[12] = 0;
930
-	result.m[13] = 0;
931
-	result.m[14] = 0;
932
-	result.m[15] = 1;
933
-	return result;
934
-}
935
-
936
-vec3 vec4tovec3(vec4 v)
937
-{
938
-	vec3 result;
939
-	result.x = v.x;
940
-	result.y = v.y;
941
-	result.z = v.z;
942
-	return result;
943
-}
944
-
945
-vec4 vec3tovec4(vec3 v)
946
-{
947
-	vec4 result;
948
-	result.x = v.x;
949
-	result.y = v.y;
950
-	result.z = v.z;
951
-	result.w = 1;
952
-	return result;
953
-}
954
-
955
-
956
-// Stol... I mean adapted from glMatrix (WebGL math unit). Almost no
957
-// changes despite changing language! But I just might replace it with
958
-// a gaussian elimination some time.
959
-mat4 InvertMat4(mat4 a)
960
-{
961
-   mat4 b;
962
-     
963
-   float c=a.m[0],d=a.m[1],e=a.m[2],g=a.m[3],
964
-	f=a.m[4],h=a.m[5],i=a.m[6],j=a.m[7],
965
-	k=a.m[8],l=a.m[9],o=a.m[10],m=a.m[11],
966
-	n=a.m[12],p=a.m[13],r=a.m[14],s=a.m[15],
967
-	A=c*h-d*f,
968
-	B=c*i-e*f,
969
-	t=c*j-g*f,
970
-	u=d*i-e*h,
971
-	v=d*j-g*h,
972
-	w=e*j-g*i,
973
-	x=k*p-l*n,
974
-	y=k*r-o*n,
975
-	z=k*s-m*n,
976
-	C=l*r-o*p,
977
-	D=l*s-m*p,
978
-	E=o*s-m*r,
979
-	q=1/(A*E-B*D+t*C+u*z-v*y+w*x);
980
-	b.m[0]=(h*E-i*D+j*C)*q;
981
-	b.m[1]=(-d*E+e*D-g*C)*q;
982
-	b.m[2]=(p*w-r*v+s*u)*q;
983
-	b.m[3]=(-l*w+o*v-m*u)*q;
984
-	b.m[4]=(-f*E+i*z-j*y)*q;
985
-	b.m[5]=(c*E-e*z+g*y)*q;
986
-	b.m[6]=(-n*w+r*t-s*B)*q;
987
-	b.m[7]=(k*w-o*t+m*B)*q;
988
-	b.m[8]=(f*D-h*z+j*x)*q;
989
-	b.m[9]=(-c*D+d*z-g*x)*q;
990
-	b.m[10]=(n*v-p*t+s*A)*q;
991
-	b.m[11]=(-k*v+l*t-m*A)*q;
992
-	b.m[12]=(-f*C+h*y-i*x)*q;
993
-	b.m[13]=(c*C-d*y+e*x)*q;
994
-	b.m[14]=(-n*u+p*B-r*A)*q;
995
-	b.m[15]=(k*u-l*B+o*A)*q;
996
-	return b;
997
-};
998
-
999
-
1000
-// Two convenient printing functions suggested by Christian Luckey 2015.
1001
-// Added printMat3 2019.
1002
-void printMat4(mat4 m)
1003
-{
1004
-	unsigned int i;
1005
-	printf(" ---------------------------------------------------------------\n");
1006
-	for (i = 0; i < 4; i++)
1007
-	{
1008
-		int n = i * 4;
1009
-		printf("| %11.5f\t| %11.5f\t| %11.5f\t| %11.5f\t|\n",
1010
-			m.m[n], m.m[n+1], m.m[n+2], m.m[n+3]);
1011
-	}
1012
-	printf(" ---------------------------------------------------------------\n");
1013
-}
1014
-
1015
-void printMat3(mat3 m)
1016
-{
1017
-	unsigned int i;
1018
-	printf(" ---------------------------------------------------------------\n");
1019
-	for (i = 0; i < 3; i++)
1020
-	{
1021
-		int n = i * 3;
1022
-		printf("| %11.5f\t| %11.5f\t| %11.5f\t| \n",
1023
-			m.m[n], m.m[n+1], m.m[n+2]);
1024
-	}
1025
-	printf(" ---------------------------------------------------------------\n");
1026
-}
1027
-
1028
-void printVec3(vec3 in) 
1029
-{
1030
-	printf("(%f, %f, %f)\n", in.x, in.y, in.z);
1031
-}
1032
-
1033
-
1034
-
1035
-/* Utility functions for easier uploads to shaders with error messages. */
1036
-// NEW as prototype 2022, added to VU 2023
1037
-
1038
-#define NUM_ERRORS 8
1039
-
1040
-static void ReportError(const char *caller, const char *name)
1041
-{
1042
-	static unsigned int draw_error_counter = 0; 
1043
-	if(draw_error_counter < NUM_ERRORS)
1044
-	{
1045
-		fprintf(stderr, "%s warning: '%s' not found in shader!\n", caller, name);
1046
-		draw_error_counter++;
1047
-	}
1048
-	else if(draw_error_counter == NUM_ERRORS)
1049
-	{
1050
-		fprintf(stderr, "%s: Number of errors bigger than %i. No more vill be printed.\n", caller, NUM_ERRORS);
1051
-		draw_error_counter++;
1052
-	}
1053
-}
1054
-
1055
-void uploadMat4ToShader(GLuint shader, char *nameInShader, mat4 m)
1056
-{
1057
-	if (nameInShader == NULL) return;
1058
-	glUseProgram(shader);
1059
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1060
-	if (loc >= 0)
1061
-		glUniformMatrix4fv(loc, 1, GL_TRUE, m.m);
1062
-	else
1063
-		ReportError("uploadMat4ToShader", nameInShader);
1064
-}
1065
-
1066
-void uploadUniformIntToShader(GLuint shader, char *nameInShader, GLint i)
1067
-{
1068
-	if (nameInShader == NULL) return;
1069
-	glUseProgram(shader);
1070
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1071
-	if (loc >= 0)
1072
-		glUniform1i(loc, i);
1073
-	else
1074
-		ReportError("uploadUniformIntToShader", nameInShader);
1075
-}
1076
-
1077
-void uploadUniformFloatToShader(GLuint shader, char *nameInShader, GLfloat f)
1078
-{
1079
-	if (nameInShader == NULL) return;
1080
-	glUseProgram(shader);
1081
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1082
-	if (loc >= 0)
1083
-		glUniform1f(loc, f);
1084
-	else
1085
-		ReportError("uploadUniformFloatToShader", nameInShader);
1086
-}
1087
-
1088
-void uploadUniformFloatArrayToShader(GLuint shader, char *nameInShader, GLfloat *f, int arrayLength)
1089
-{
1090
-	if (nameInShader == NULL) return;
1091
-	glUseProgram(shader);
1092
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1093
-	if (loc >= 0)
1094
-		glUniform1fv(loc, arrayLength, f);
1095
-	else
1096
-		ReportError("uploadUniformFloatToShader", nameInShader);
1097
-}
1098
-
1099
-void uploadUniformVec3ToShader(GLuint shader, char *nameInShader, vec3 v)
1100
-{
1101
-	if (nameInShader == NULL) return;
1102
-	glUseProgram(shader);
1103
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1104
-	if (loc >= 0)
1105
-		glUniform3f(loc, v.x, v.y, v.z);
1106
-	else
1107
-		ReportError("uploadUniformVec3ToShader", nameInShader);
1108
-}
1109
-
1110
-void uploadUniformVec3ArrayToShader(GLuint shader, char *nameInShader, vec3 *a, int arrayLength)
1111
-{
1112
-	if (nameInShader == NULL) return;
1113
-	glUseProgram(shader);
1114
-	GLint loc = glGetUniformLocation(shader, nameInShader);
1115
-	if (loc >= 0)
1116
-		glUniform3fv(loc, arrayLength, (GLfloat *)a);
1117
-	else
1118
-		ReportError("uploadUniformVec3ArrayToShader", nameInShader);
1119
-}
1120
-
1121
-void bindTextureToTextureUnit(GLuint tex, int unit)
1122
-{
1123
-	glActiveTexture(GL_TEXTURE0 + unit);
1124
-	glBindTexture(GL_TEXTURE_2D, tex);
1125
-}
1126 0
deleted file mode 100755
... ...
@@ -1,376 +0,0 @@
1
-// VectorUtils3 header
2
-// See source for more information
3
-
4
-#ifndef VECTORUTILS3
5
-#define VECTORUTILS3
6
-
7
-#ifdef __APPLE__
8
-	#define GL_SILENCE_DEPRECATION
9
-	#include <OpenGL/gl3.h>
10
-#else
11
-	#if defined(_WIN32)
12
-		#include "glew.h"
13
-	#endif
14
-	#include <GL/gl.h>
15
-#endif
16
-#include <math.h>
17
-#include <stdio.h>
18
-
19
-
20
-#ifndef M_PI
21
-#define M_PI           3.14159265358979323846
22
-#endif
23
-
24
-// Really old type names
25
-#define Vector3f Point3D
26
-#define Matrix3f Matrix3D
27
-#define Matrix4f Matrix4D
28
-
29
-// GLSL-style
30
-// These are already changed, here I define the intermediate type names that I use in some demos.
31
-#define Point3D vec3
32
-#define Matrix3D mat3
33
-#define Matrix4D mat4
34
-// These are not changed below yet
35
-#define dot DotProduct
36
-#define cross CrossProduct
37
-#define normalize Normalize
38
-// Furthermore, SplitVector should be revised to conform with reflect()
39
-
40
-
41
-// Note 210515: I have removed the constructors from my structs below in order to please
42
-// some compilers. They did work but the compilers were upset about C using these
43
-// without knowing about the constructors, while the C++ code happily used them.
44
-// However, we do not need them; you can initialize with SetVec* instead of
45
-// vec*() and it will work.
46
-
47
-	// vec3 is very useful
48
-	typedef struct vec3
49
-	{
50
-		GLfloat x, y, z;
51
-//		#ifdef __cplusplus
52
-//            vec3() {}
53
-//			vec3(GLfloat x2, GLfloat y2, GLfloat z2) : x(x2), y(y2), z(z2) {}
54
-
55
-////			vec3(vec4 v) : x(v.x), y(v.y), z(v.z) {}
56
-//		#endif
57
-	} vec3, *vec3Ptr;
58
-	
59
-	// vec4 is not as useful. Can be a color with alpha, or a quaternion, but IMHO you
60
-	// rarely need homogenous coordinate vectors on the CPU.
61
-	typedef struct vec4
62
-	{
63
-		GLfloat x, y, z, w; // w or h
64
-//		#ifdef __cplusplus
65
-//            vec4() {}
66
-//			vec4(GLfloat x2, GLfloat y2, GLfloat z2, GLfloat w2) : x(x2), y(y2), z(z2), w(w2) {}
67
-//			vec4(GLfloat xyz, GLfloat w2) : x(xyz), y(xyz), z(xyz), w(w2) {}
68
-//			vec4(vec3 v, GLfloat w2) : x(v.x), y(v.y), z(v.z), w(w2) {}
69
-//			
70
-//			vec4(vec3 v) : x(v.x), y(v.y), z(v.z), w(1) {}
71
-//		#endif
72
-	} vec4, *vec4Ptr;
73
-
74
-// vec2 is mostly used for texture cordinates, so I havn't bothered defining any operations for it
75
-	typedef struct vec2
76
-	{
77
-		GLfloat x, y;
78
-//		#ifdef __cplusplus
79
-//            vec2() {}
80
-//			vec2(GLfloat x2, GLfloat y2) : x(x2), y(y2) {}
81
-//		#endif
82
-	} vec2, *vec2Ptr;
83
-	
84
-
85
-	typedef struct mat4
86
-	{
87
-		GLfloat m[16];
88
-	} mat4;
89
-	typedef struct mat3
90
-	{
91
-		GLfloat m[9];
92
-	} mat3;
93
-
94
-#ifdef __cplusplus
95
-extern "C" {
96
-#endif
97
-
98
-// New better name for SetVector and replacements for constructors
99
-	vec2 SetVec2(GLfloat x, GLfloat y);
100
-	vec3 SetVec3(GLfloat x, GLfloat y, GLfloat z);
101
-	vec4 SetVec4(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
102
-
103
-//	void CopyVector(vec3 *v, vec3 *dest); // Will probably be removed
104
-	vec3 SetVector(GLfloat x, GLfloat y, GLfloat z);
105
-	mat3 SetMat3(GLfloat p0, GLfloat p1, GLfloat p2, GLfloat p3, GLfloat p4, GLfloat p5, GLfloat p6, GLfloat p7, GLfloat p8);
106
-	mat4 SetMat4(GLfloat p0, GLfloat p1, GLfloat p2, GLfloat p3,
107
-				GLfloat p4, GLfloat p5, GLfloat p6, GLfloat p7,
108
-				GLfloat p8, GLfloat p9, GLfloat p10, GLfloat p11, 
109
-				GLfloat p12, GLfloat p13, GLfloat p14, GLfloat p15
110
-				);
111
-// Basic vector operations on vec3's. (vec4 not included since I never need them.)
112
-	vec3 VectorSub(vec3 a, vec3 b);
113
-	vec3 VectorAdd(vec3 a, vec3 b);
114
-	vec3 CrossProduct(vec3 a, vec3 b);
115
-	GLfloat DotProduct(vec3 a, vec3 b);
116
-	vec3 ScalarMult(vec3 a, GLfloat s);
117
-	GLfloat Norm(vec3 a);
118
-	vec3 Normalize(vec3 a);
119
-	vec3 CalcNormalVector(vec3 a, vec3 b, vec3 c);
120
-	void SplitVector(vec3 v, vec3 n, vec3 *vn, vec3 *vp);
121
-
122
-// Matrix operations primarily on 4x4 matrixes!
123
-// Row-wise by default but can be configured to column-wise (see SetTransposed)
124
-
125
-	mat4 IdentityMatrix();
126
-	mat4 Rx(GLfloat a);
127
-	mat4 Ry(GLfloat a);
128
-	mat4 Rz(GLfloat a);
129
-	mat4 T(GLfloat tx, GLfloat ty, GLfloat tz);
130
-	mat4 S(GLfloat sx, GLfloat sy, GLfloat sz);
131
-	mat4 Mult(mat4 a, mat4 b); // dest = a * b - rename to MultMat4 considered but I don't like to make the name of the most common operation longer
132
-	// but for symmetry, MultMat4 is made a synonym:
133
-	#define MultMat4 Mult
134
-
135
-	// Was MatrixMultPoint3D
136
-	vec3 MultVec3(mat4 a, vec3 b); // result = a * b
137
-	vec4 MultVec4(mat4 a, vec4 b);
138
-//	void CopyMatrix(GLfloat *src, GLfloat *dest); // Will probably be removed
139
-
140
-// Mat3 operations (new)
141
-	mat3 MultMat3(mat3 a, mat3 b); // m = a * b
142
-	vec3 MultMat3Vec3(mat3 a, vec3 b); // result = a * b
143
-
144
-	void OrthoNormalizeMatrix(mat4 *R);
145
-	mat4 transpose(mat4 m);
146
-//	mat4 TransposeRotation(mat4 m); // Will probably be removed
147
-	mat3 TransposeMat3(mat3 m);
148
-	mat4 ArbRotate(vec3 axis, GLfloat fi);
149
-	mat4 CrossMatrix(vec3 a);
150
-	mat4 MatrixAdd(mat4 a, mat4 b);
151
-
152
-// Configure, i.e. if you want matrices to be column-wise
153
-	void SetTransposed(char t);
154
-
155
-// GLU replacement functions
156
-	mat4 lookAtv(vec3 p, vec3 l, vec3 v);
157
-	mat4 lookAt(GLfloat px, GLfloat py, GLfloat pz, 
158
-			GLfloat lx, GLfloat ly, GLfloat lz,
159
-			GLfloat vx, GLfloat vy, GLfloat vz);
160
-	mat4 perspective(float fovyInDegrees, float aspectRatio,
161
-                      float znear, float zfar);
162
-	mat4 frustum(float left, float right, float bottom, float top,
163
-                  float znear, float zfar);
164
-	mat4 ortho(GLfloat left, GLfloat right, GLfloat bottom,
165
-			GLfloat top, GLfloat near, GLfloat far);
166
-
167
-// For creating a normal matrix
168
-	mat3 InvertMat3(mat3 in);
169
-	mat3 InverseTranspose(mat4 in);
170
-	mat4 InvertMat4(mat4 a);
171
-
172
-// Simple conversions
173
-	mat3 mat4tomat3(mat4 m);
174
-	mat4 mat3tomat4(mat3 m);
175
-	vec3 vec4tovec3(vec4 v);
176
-	vec4 vec3tovec4(vec3 v);
177
-
178
-// Convenient printing calls
179
-	void printMat4(mat4 m);
180
-	void printVec3(vec3 in);
181
-
182
-/* Utility functions for easier uploads to shaders with error messages. */
183
-// NEW as prototype 2022, added to VU 2023
184
-	void uploadMat4ToShader(GLuint shader, char *nameInShader, mat4 m);
185
-	void uploadUniformIntToShader(GLuint shader, char *nameInShader, GLint i);
186
-	void uploadUniformFloatToShader(GLuint shader, char *nameInShader, GLfloat f);
187
-	void uploadUniformFloatArrayToShader(GLuint shader, char *nameInShader, GLfloat *f, int arrayLength);
188
-	void uploadUniformVec3ToShader(GLuint shader, char *nameInShader, vec3 v);
189
-	void uploadUniformVec3ArrayToShader(GLuint shader, char *nameInShader, vec3 *a, int arrayLength);
190
-	void bindTextureToTextureUnit(GLuint tex, int unit);
191
-
192
-
193
-
194
-#ifdef __cplusplus
195
-}
196
-#endif
197
-
198
-#ifdef __cplusplus
199
-// Some C++ operator overloads
200
-// Non-member C++ operators!
201
-// New version 2021-05-2x: Constructiors for vec3 etc replaced in order to avoid
202
-// problems with some C++ compilers.
203
-
204
-// --- vec3 operations ---
205
-inline
206
-vec3 operator+(const vec3 &a, const vec3 &b) // vec3+vec3
207
-{
208
-	return SetVector(a.x+b.x, a.y+b.y, a.z+b.z);
209
-}
210
-
211
-inline
212
-vec3 operator-(const vec3 &a, const vec3 &b) // vec3-vec3
213
-{
214
-	return SetVector(a.x-b.x, a.y-b.y, a.z-b.z);
215
-}
216
-
217
-inline
218
-vec3 operator-(const vec3 &a)
219
-{
220
-		return SetVector(-a.x, -a.y, -a.z);
221
-}
222
-
223
-	// Questionable, not like GLSL
224
-inline
225
-float operator*(const vec3 &a, const vec3 &b) // vec3 dot vec3
226
-{
227
-	return (a.x*b.x+ a.y*b.y+ a.z*b.z);
228
-}
229
-
230
-inline
231
-vec3 operator*(const vec3 &b, double a) // vec3 * scalar
232
-{
233
-	return SetVector(a*b.x, a*b.y, a*b.z);
234
-}
235
-
236
-inline
237
-vec3 operator*(double a, const vec3 &b) // scalar * vec3
238
-{
239
-	return SetVector(a*b.x, a*b.y, a*b.z);
240
-}
241
-
242
-inline
243
-vec3 operator/(const vec3 &b, double a) // vec3 / scalar
244
-{
245
-	return SetVector(b.x/a, b.y/a, b.z/a);
246
-}
247
-
248
-inline
249
-void operator+=(vec3 &a, const vec3 &b) // vec3+=vec3
250
-{
251
-	a = a + b;
252
-}
253
-
254
-inline
255
-void operator-=(vec3 &a, const vec3 &b) // vec3-=vec3
256
-{
257
-	a = a - b;
258
-}
259
-
260
-inline
261
-void operator*=(vec3 &a, const float &b) // vec3*=scalar
262
-{
263
-	a = a * b;
264
-}
265
-
266
-inline
267
-void operator/=(vec3 &a, const float &b) // vec3/=scalar
268
-{
269
-	a = a / b;
270
-}
271
-
272
-// --- vec4 operations ---
273
-
274
-inline
275
-vec4 operator+(const vec4 &a, const vec4 &b) // vec4+vec4
276
-{
277
-	return SetVec4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
278
-}
279
-
280
-inline
281
-vec4 operator-(const vec4 &a, const vec4 &b) // vec4-vec4
282
-{
283
-	return SetVec4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w);
284
-}
285
-
286
-	// Questionable, not like GLSL
287
-inline
288
-float operator*(const vec4 &a, const vec4 &b) // vec4 dot vec4
289
-{
290
-	return (a.x*b.x+ a.y*b.y+ a.z*b.z+ a.w*b.w);
291
-}
292
-
293
-inline
294
-vec4 operator*(const vec4 &b, double a) // vec4 * scalar
295
-{
296
-	return SetVec4(a*b.x, a*b.y, a*b.z, a*b.w);
297
-}
298
-
299
-inline
300
-vec4 operator*(double a, const vec4 &b) // scalar * vec4
301
-{
302
-	return SetVec4(a*b.x, a*b.y, a*b.z, a*b.w);
303
-}
304
-
305
-inline
306
-vec4 operator/(const vec4 &b, double a) // vec4 / scalar
307
-{
308
-	return SetVec4(b.x/a, b.y/a, b.z/a, b.w/a);
309
-}
310
-
311
-
312
-inline
313
-void operator+=(vec4 &a, const vec4 &b) // vec4+=vec4
314
-{
315
-	a = a + b;
316
-}
317
-
318
-inline
319
-void operator-=(vec4 &a, const vec4 &b) // vec4-=vec4
320
-{
321
-	a = a - b;
322
-}
323
-
324
-inline
325
-void operator*=(vec4 &a, const float &b) // vec4 *= scalar
326
-{
327
-	a = a * b;
328
-}
329
-
330
-inline
331
-void operator/=(vec4 &a, const float &b) // vec4 /= scalar
332
-{
333
-	a = a / b;
334
-}
335
-
336
-// --- Matrix multiplication ---
337
-
338
-// mat4 * mat4
339
-inline
340
-mat4 operator*(const mat4 &a, const mat4 &b)
341
-{
342
-	return (Mult(a, b));
343
-}
344
-
345
-// mat3 * mat3
346
-inline
347
-mat3 operator*(const mat3 &a, const mat3 &b)
348
-{
349
-	return (MultMat3(a, b));
350
-}
351
-
352
-// mat4 * vec3
353
-inline
354
-vec3 operator*(const mat4 &a, const vec3 &b)
355
-{
356
-	return MultVec3(a, b); // result = a * b
357
-}
358
-
359
-// mat4 * vec4
360
-inline
361
-vec4 operator*(const mat4 &a, const vec4 &b)
362
-{
363
-	return MultVec4(a, b); // result = a * b
364
-}
365
-
366
-// mat3 * vec3
367
-inline
368
-vec3 operator*(const mat3 &a, const vec3 &b)
369
-{
370
-	return MultMat3Vec3(a, b); // result = a * b
371
-}
372
-
373
-#endif
374
-
375
-
376
-#endif
... ...
@@ -73,7 +73,7 @@
73 73
 // 170331: Added stdio.h for printMat4 and printVec3
74 74
 // 180314: Added some #defines for moving closer to GLSL (dot, cross...).
75 75
 // 2021-05-15: Constructors for vec3 etc replaced in order to avoid
76
-// problems with some C++ compilers.
76
+// problems with some C++ compilers.
77 77
 // 2022-11-10: Corrected an ifdef that could cause problems.
78 78
 
79 79
 // 2022-05-05: Created VectorUtils4, now only a header file!
... ...
@@ -352,6 +352,18 @@
352 352
 	void printMat4(mat4 m);
353 353
 	void printVec3(vec3 in);
354 354
 
355
+/* Utility functions for easier uploads to shaders with error messages. */
356
+// NEW as prototype 2022, added to VU 2023
357
+/*
358
+	void uploadMat4ToShader(GLuint shader, char *nameInShader, mat4 m);
359
+	void uploadUniformIntToShader(GLuint shader, char *nameInShader, GLint i);
360
+	void uploadUniformFloatToShader(GLuint shader, char *nameInShader, GLfloat f);
361
+	void uploadUniformFloatArrayToShader(GLuint shader, char *nameInShader, GLfloat *f, int arrayLength);
362
+	void uploadUniformVec3ToShader(GLuint shader, char *nameInShader, vec3 v);
363
+	void uploadUniformVec3ArrayToShader(GLuint shader, char *nameInShader, vec3 *a, int arrayLength);
364
+	void bindTextureToTextureUnit(GLuint tex, int unit);
365
+*/
366
+
355 367
 #ifdef __cplusplus
356 368
 // Convenient overloads for C++, closer to GLSL
357 369
 	mat3 inverse(mat3 m);
... ...
@@ -547,7 +559,7 @@ vec3 operator*(const mat3 &a, const vec3 &b)
547 559
 // ********** implementation section ************
548 560
 
549 561
 #ifdef MAIN
550
-//#ifndef VECTOR_UTILS_IMPLEMENTATION
562
+//#ifndef VECTOR_UTILS_IMPLEMENTATION
551 563
 //#define VECTOR_UTILS_IMPLEMENTATION
552 564
 
553 565
 // VS doesn't define NAN properly
... ...
@@ -1526,6 +1538,98 @@ void printVec3(vec3 in)
1526 1538
 	printf("(%f, %f, %f)\n", in.x, in.y, in.z);
1527 1539
 }
1528 1540
 
1541
+/* Utility functions for easier uploads to shaders with error messages. */
1542
+// NEW as prototype 2022, added to VU 2023
1543
+
1544
+#define NUM_ERRORS 8
1545
+
1546
+static void ReportError(const char *caller, const char *name)
1547
+{
1548
+	static unsigned int draw_error_counter = 0; 
1549
+	if(draw_error_counter < NUM_ERRORS)
1550
+	{
1551
+		fprintf(stderr, "%s warning: '%s' not found in shader!\n", caller, name);
1552
+		draw_error_counter++;
1553
+	}
1554
+	else if(draw_error_counter == NUM_ERRORS)
1555
+	{
1556
+		fprintf(stderr, "%s: Number of errors bigger than %i. No more vill be printed.\n", caller, NUM_ERRORS);
1557
+		draw_error_counter++;
1558
+	}
1559
+}
1560
+
1561
+void uploadMat4ToShader(GLuint shader, char *nameInShader, mat4 m)
1562
+{
1563
+	if (nameInShader == NULL) return;
1564
+	glUseProgram(shader);
1565
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1566
+	if (loc >= 0)
1567
+		glUniformMatrix4fv(loc, 1, GL_TRUE, m.m);
1568
+	else
1569
+		ReportError("uploadMat4ToShader", nameInShader);
1570
+}
1571
+
1572
+void uploadUniformIntToShader(GLuint shader, char *nameInShader, GLint i)
1573
+{
1574
+	if (nameInShader == NULL) return;
1575
+	glUseProgram(shader);
1576
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1577
+	if (loc >= 0)
1578
+		glUniform1i(loc, i);
1579
+	else
1580
+		ReportError("uploadUniformIntToShader", nameInShader);
1581
+}
1582
+
1583
+void uploadUniformFloatToShader(GLuint shader, char *nameInShader, GLfloat f)
1584
+{
1585
+	if (nameInShader == NULL) return;
1586
+	glUseProgram(shader);
1587
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1588
+	if (loc >= 0)
1589
+		glUniform1f(loc, f);
1590
+	else
1591
+		ReportError("uploadUniformFloatToShader", nameInShader);
1592
+}
1593
+
1594
+void uploadUniformFloatArrayToShader(GLuint shader, char *nameInShader, GLfloat *f, int arrayLength)
1595
+{
1596
+	if (nameInShader == NULL) return;
1597
+	glUseProgram(shader);
1598
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1599
+	if (loc >= 0)
1600
+		glUniform1fv(loc, arrayLength, f);
1601
+	else
1602
+		ReportError("uploadUniformFloatToShader", nameInShader);
1603
+}
1604
+
1605
+void uploadUniformVec3ToShader(GLuint shader, char *nameInShader, vec3 v)
1606
+{
1607
+	if (nameInShader == NULL) return;
1608
+	glUseProgram(shader);
1609
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1610
+	if (loc >= 0)
1611
+		glUniform3f(loc, v.x, v.y, v.z);
1612
+	else
1613
+		ReportError("uploadUniformVec3ToShader", nameInShader);
1614
+}
1615
+
1616
+void uploadUniformVec3ArrayToShader(GLuint shader, char *nameInShader, vec3 *a, int arrayLength)
1617
+{
1618
+	if (nameInShader == NULL) return;
1619
+	glUseProgram(shader);
1620
+	GLint loc = glGetUniformLocation(shader, nameInShader);
1621
+	if (loc >= 0)
1622
+		glUniform3fv(loc, arrayLength, (GLfloat *)a);
1623
+	else
1624
+		ReportError("uploadUniformVec3ArrayToShader", nameInShader);
1625
+}
1626
+
1627
+void bindTextureToTextureUnit(GLuint tex, int unit)
1628
+{
1629
+	glActiveTexture(GL_TEXTURE0 + unit);
1630
+	glBindTexture(GL_TEXTURE_2D, tex);
1631
+}
1632
+
1529 1633
 #ifdef __cplusplus
1530 1634
 mat3 inverse(mat3 m)
1531 1635
 {
1532 1636
deleted file mode 100755
1533 1637
Binary files a/lab1/._lab1-1.c and /dev/null differ
1534 1638
Binary files a/lab1/lab1-1 and b/lab1/lab1-1 differ
1535 1639
deleted file mode 100755
... ...
@@ -1,87 +0,0 @@
1
-// Lab 1-1.
2
-// This is the same as the first simple example in the course book,
3
-// but with a few error checks.
4
-// Remember to copy your file to a new on appropriate places during the lab so you keep old results.
5
-// Note that the files "lab1-1.frag", "lab1-1.vert" are required.
6
-
7
-#include "GL_utilities.h"
8
-#include "MicroGlut.h"
9
-// uses framework OpenGL
10
-// uses framework Cocoa
11
-
12
-// Globals
13
-// Data would normally be read from files
14
-GLfloat vertices[] =
15
-{
16
-	-0.5f,-0.5f,0.0f,
17
-	-0.5f,0.5f,0.0f,
18
-	0.5f,-0.5f,0.0f
19
-};
20
-
21
-// vertex array object
22
-unsigned int vertexArrayObjID;
23
-
24
-void init(void)
25
-{
26
-	// vertex buffer object, used for uploading the geometry
27
-	unsigned int vertexBufferObjID;
28
-	// Reference to shader program
29
-	GLuint program;
30
-
31
-	dumpInfo();
32
-
33
-	// GL inits
34
-	glClearColor(0.2,0.2,0.5,0);
35
-	glDisable(GL_DEPTH_TEST);
36
-	printError("GL inits");
37
-
38
-	// Load and compile shader
39
-	program = loadShaders("lab1-1.vert", "lab1-1.frag");
40
-	printError("init shader");
41
-	
42
-	// Upload geometry to the GPU:
43
-	
44
-	// Allocate and activate Vertex Array Object
45
-	glGenVertexArrays(1, &vertexArrayObjID);
46
-	glBindVertexArray(vertexArrayObjID);
47
-	// Allocate Vertex Buffer Objects
48
-	glGenBuffers(1, &vertexBufferObjID);
49
-	
50
-	// VBO for vertex data
51
-	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID);
52
-	glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
53
-	glVertexAttribPointer(glGetAttribLocation(program, "in_Position"), 3, GL_FLOAT, GL_FALSE, 0, 0); 
54
-	glEnableVertexAttribArray(glGetAttribLocation(program, "in_Position"));
55
-	
56
-	// End of upload of geometry
57
-	
58
-	printError("init arrays");
59
-}
60
-
61
-
62
-void display(void)
63
-{
64
-	printError("pre display");
65
-
66
-	// clear the screen
67
-	glClear(GL_COLOR_BUFFER_BIT);
68
-
69
-	glBindVertexArray(vertexArrayObjID);	// Select VAO
70
-	glDrawArrays(GL_TRIANGLES, 0, 3);	// draw object
71
-	
72
-	printError("display");
73
-	
74
-	glutSwapBuffers();
75
-}
76
-
77
-int main(int argc, char *argv[])
78
-{
79
-	glutInit(&argc, argv);
80
-	glutInitContextVersion(3, 2);
81
-	glutInitWindowSize(600, 600);
82
-	glutCreateWindow ("GL3 white triangle example");
83
-	glutDisplayFunc(display); 
84
-	init ();
85
-	glutMainLoop();
86
-	return 0;
87
-}
88 0
deleted file mode 100755
... ...
@@ -1 +0,0 @@
1
-Targ0
1
4
Path0
23
../common
../common/Mac
2 0
\ No newline at end of file
... ...
@@ -4,7 +4,7 @@ commondir = ../common/
4 4
 all : lab1-1
5 5
 
6 6
 lab1-1 : lab1-1.cpp $(commondir)GL_utilities.c $(commondir)LoadTGA.c $(commondir)Linux/MicroGlut.c
7
-	gcc -Wall -o lab1-1 -I$(commondir) -I../common/Linux -DGL_GLEXT_PROTOTYPES lab1-1.cpp $(commondir)GL_utilities.c $(commondir)LoadTGA.c $(commondir)Linux/MicroGlut.c -lXt -lX11 -lGL -lm
7
+	gcc -Wall -o lab1-1 -I$(commondir) -I../common/Linux -DGL_GLEXT_PROTOTYPES lab1-1.cpp $(commondir)GL_utilities.c $(commondir)LoadTGA.c $(commondir)Linux/MicroGlut.c -lXt -lX11 -lGL -lm -lstdc++
8 8
 
9 9
 clean :
10 10
 	rm lab1-1
11 11
deleted file mode 100755
12 12
Binary files a/lab3/._labskybox.obj and /dev/null differ
13 13
deleted file mode 100755
14 14
Binary files a/lab3/._labskybox512.tga and /dev/null differ
15 15
deleted file mode 100755
... ...
@@ -1,43 +0,0 @@
1
-# Exported from Wings 3D 0.98.26b
2
-mtllib cube.mtl
3
-o cube1
4
-#8 vertices, 6 faces
5
-v -2.0 -0.0 2.0
6
-v -2.0 2.0 2.0
7
-v 2.0 2.0 2.0
8
-v 2.0 -0.0 2.0
9
-v -2.0 -0.0 -2.0
10
-v -2.0 2.0 -2.0
11
-v 2.0 2.0 -2.0
12
-v 2.0 -0.0 -2.0
13
-vn -0.57735027 -0.57735027 0.57735027
14
-vn -0.57735027 0.57735027 0.57735027
15
-vn 0.57735027 0.57735027 0.57735027
16
-vn 0.57735027 -0.57735027 0.57735027
17
-vn -0.57735027 -0.57735027 -0.57735027
18
-vn -0.57735027 0.57735027 -0.57735027
19
-vn 0.57735027 0.57735027 -0.57735027
20
-vn 0.57735027 -0.57735027 -0.57735027
21
-vt 0.25 0.0
22
-vt 0.75 0.0
23
-
24
-vt 0.0 0.25
25
-vt 0.25 0.25
26
-vt 0.75 0.25
27
-vt 1.0 0.25
28
-
29
-vt 0.0 0.75
30
-vt 0.25 0.75
31
-vt 0.75 0.75
32
-vt 1.0 0.75
33
-
34
-vt 0.25 1.0
35
-vt 0.75 1.0
36
-
37
-g cube1_default
38
-usemtl default
39
-f 3/9/3 2/8/2 1/11/1 4/12/4
40
-f 5/3/5 1/7/1 2/8/2 6/4/6
41
-f 6/4/6 2/8/2 3/9/3 7/5/7
42
-f 7/5/7 3/9/3 4/10/4 8/6/8
43
-f 8/2/8 5/1/5 6/4/6 7/5/7
44 0
deleted file mode 100755
45 1
Binary files a/lab3/labskybox512.tga and /dev/null differ
46 2
deleted file mode 100755
47 3
Binary files a/lab4/._fft-terrain1024c.tga and /dev/null differ
48 4
deleted file mode 100755
49 5
Binary files a/lab4/._lab4-1.c and /dev/null differ
50 6
deleted file mode 100755
... ...
@@ -1,159 +0,0 @@
1
-// Lab 4, terrain generation
2
-
3
-	// uses framework Cocoa
4
-	// uses framework OpenGL
5
-#include "MicroGlut.h"
6
-#include "GL_utilities.h"
7
-#include "VectorUtils3.h"
8
-#include "LittleOBJLoader.h"
9
-#include "LoadTGA.h"
10
-
11
-mat4 projectionMatrix;
12
-
13
-Model* GenerateTerrain(TextureData *tex)
14
-{
15
-	int vertexCount = tex->width * tex->height;
16
-	int triangleCount = (tex->width-1) * (tex->height-1) * 2;
17
-	int x, z;
18
-	
19
-	vec3 *vertexArray = (vec3 *)malloc(sizeof(GLfloat) * 3 * vertexCount);
20
-	vec3 *normalArray = (vec3 *)malloc(sizeof(GLfloat) * 3 * vertexCount);
21
-	vec2 *texCoordArray = (vec2 *)malloc(sizeof(GLfloat) * 2 * vertexCount);
22
-	GLuint *indexArray = malloc(sizeof(GLuint) * triangleCount*3);
23
-	
24
-	printf("bpp %d\n", tex->bpp);
25
-	for (x = 0; x < tex->width; x++)
26
-		for (z = 0; z < tex->height; z++)
27
-		{
28
-// Vertex array. You need to scale this properly
29
-			vertexArray[(x + z * tex->width)].x = x / 1.0;
30
-			vertexArray[(x + z * tex->width)].y = tex->imageData[(x + z * tex->width) * (tex->bpp/8)] / 100.0;
31
-			vertexArray[(x + z * tex->width)].z = z / 1.0;
32
-// Normal vectors. You need to calculate these.
33
-			normalArray[(x + z * tex->width)].x = 0.0;
34
-			normalArray[(x + z * tex->width)].y = 1.0;
35
-			normalArray[(x + z * tex->width)].z = 0.0;
36
-// Texture coordinates. You may want to scale them.
37
-			texCoordArray[(x + z * tex->width)].x = x; // (float)x / tex->width;
38
-			texCoordArray[(x + z * tex->width)].y = z; // (float)z / tex->height;
39
-		}
40
-	for (x = 0; x < tex->width-1; x++)
41
-		for (z = 0; z < tex->height-1; z++)
42
-		{
43
-		// Triangle 1
44
-			indexArray[(x + z * (tex->width-1))*6 + 0] = x + z * tex->width;
45
-			indexArray[(x + z * (tex->width-1))*6 + 1] = x + (z+1) * tex->width;
46
-			indexArray[(x + z * (tex->width-1))*6 + 2] = x+1 + z * tex->width;
47
-		// Triangle 2
48
-			indexArray[(x + z * (tex->width-1))*6 + 3] = x+1 + z * tex->width;
49
-			indexArray[(x + z * (tex->width-1))*6 + 4] = x + (z+1) * tex->width;
50
-			indexArray[(x + z * (tex->width-1))*6 + 5] = x+1 + (z+1) * tex->width;
51
-		}
52
-	
53
-	// End of terrain generation
54
-	
55
-	// Create Model and upload to GPU:
56
-	
57
-	Model* model = LoadDataToModel(
58
-			vertexArray,
59
-			normalArray,
60
-			texCoordArray,
61
-			NULL,
62
-			indexArray,
63
-			vertexCount,
64
-			triangleCount*3);
65
-
66
-	return model;
67
-}
68
-
69
-
70
-// vertex array object
71
-Model *m, *m2, *tm;
72
-// Reference to shader program
73
-GLuint program;
74
-GLuint tex1, tex2;
75
-TextureData ttex; // terrain
76
-
77
-void init(void)
78
-{
79
-	// GL inits
80
-	glClearColor(0.4,0.6,1.0,0);
81
-	glEnable(GL_DEPTH_TEST);
82
-	glDisable(GL_CULL_FACE);
83
-	printError("GL inits");
84
-
85
-	projectionMatrix = frustum(-0.1, 0.1, -0.1, 0.1, 0.2, 50.0);
86
-
87
-	// Load and compile shader
88
-	program = loadShaders("terrain.vert", "terrain.frag");
89
-	glUseProgram(program);
90
-	printError("init shader");
91
-	
92
-	glUniformMatrix4fv(glGetUniformLocation(program, "projMatrix"), 1, GL_TRUE, projectionMatrix.m);
93
-	glUniform1i(glGetUniformLocation(program, "tex"), 0); // Texture unit 0
94
-	LoadTGATextureSimple("maskros512.tga", &tex1);
95
-	
96
-// Load terrain data
97
-	
98
-	LoadTGATextureData("44-terrain.tga", &ttex);
99
-	tm = GenerateTerrain(&ttex);
100
-	printError("init terrain");
101
-
102
-	printf("Note: The call to DrawModel will report warnings about inNormal not existing. This is because inNormal is not used in the shader yet so it is optimized away.\n");
103
-
104
-}
105
-
106
-void display(void)
107
-{
108
-	// clear the screen
109
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
110
-	
111
-	mat4 total, modelView, camMatrix;
112
-	
113
-	printError("pre display");
114
-	
115
-	glUseProgram(program);
116
-
117
-	// Build matrix
118
-	
119
-	vec3 cam = {0, 5, 8};
120
-	vec3 lookAtPoint = {2, 0, 2};
121
-	camMatrix = lookAt(cam.x, cam.y, cam.z,
122
-				lookAtPoint.x, lookAtPoint.y, lookAtPoint.z,
123
-				0.0, 1.0, 0.0);
124
-	modelView = IdentityMatrix();
125
-	total = Mult(camMatrix, modelView);
126
-	glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, total.m);
127
-	
128
-	glBindTexture(GL_TEXTURE_2D, tex1);		// Bind Our Texture tex1
129
-
130
-	DrawModel(tm, program, "inPosition", "inNormal", "inTexCoord");
131
-
132
-	printError("display 2");
133
-	
134
-	glutSwapBuffers();
135
-}
136
-
137
-void mouse(int x, int y)
138
-{
139
-	// This function is included in case you want some hints about using passive mouse movement.
140
-	// Uncomment to see mouse coordinates:
141
-	// printf("%d %d\n", x, y);
142
-}
143
-
144
-int main(int argc, char **argv)
145
-{
146
-	glutInit(&argc, argv);
147
-	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
148
-	glutInitContextVersion(3, 2);
149
-	glutInitWindowSize (600, 600);
150
-	glutCreateWindow ("TSBK07 Lab 4");
151
-	glutDisplayFunc(display);
152
-	init ();
153
-	glutRepeatingTimer(20);
154
-	
155
-	glutPassiveMotionFunc(mouse);
156
-
157
-	glutMainLoop();
158
-	exit(0);
159
-}